primitive long and double compatibility

Hi ranchers!

I cannot fully understand the in/compatibility between long and double;

The following code points out that long can be converted into double, but it's illegal the contrary.

What puzzles me is that both primitives are ranged as 64 bit number.

So how is that possible?

I cannot fully understand the in/compatibility between long and double;

The following code points out that long can be converted into double, but it's illegal the contrary.

What puzzles me is that both primitives are ranged as 64 bit number.

So how is that possible?

Please remember that a double can handle factions/decimal numbers for instance 3.141592654 as well as whole numbers.

Where as long can not handle factions/decimal numbers, but only whole numbers.

Given your example code**x** is a whole number of 1000.

It then automatically gets converted to a double when you declare**y**.

Now**y** is 1000.00, or something close to that because it's a double.

1000.00 cannot be converted to**int** without the loosing the decimal places. In doing so you may lose some precision.

This is somewhat related to this posting/blog entry

Does 1.0 equal 0.9999999999999999...?

Which attempts to explain some of the concerns with dealing to floating point numbers in regards to comparisons.

Where as long can not handle factions/decimal numbers, but only whole numbers.

Given your example code

It then automatically gets converted to a double when you declare

Now

1000.00 cannot be converted to

This is somewhat related to this posting/blog entry

Does 1.0 equal 0.9999999999999999...?

Which attempts to explain some of the concerns with dealing to floating point numbers in regards to comparisons.

You are not using the number as a` long`.` 1_000 `is an` int `literal, which requires conversion to a` long `before you can use it. The` long `form of the number is` 1_000L`.

What PL has said is the explanation for a basic language requirement: a` double `is regarded as a “wider” datatype that a` long`, so you can implicitly widen one way, but you cannot convert the other way without a cast. As PL has hinted, the cast will lose any fractional part of the number.

You can also get loss of precision the other way; it is possible to fit 1234567891011121314L into a` long`, but there is no guarantee that it can be exactly represented as a` double`.

1000 is one of the numbers that can be represented exactly as a` double`.

What PL has said is the explanation for a basic language requirement: a

You can also get loss of precision the other way; it is possible to fit 1234567891011121314L into a

1000 is one of the numbers that can be represented exactly as a

Pete Letkeman wrote:Please remember that a double can handle factions/decimal numbers for instance 3.141592654 as well as whole numbers.

Where as long can not handle factions/decimal numbers, but only whole numbers.

Given your example codexis a whole number of 1000.

It then automatically gets converted to a double when you declarey.

Nowyis 1000.00, or something close to that because it's a double.

1000.00 cannot be converted tointwithout the loosing the decimal places. In doing so you may lose some precision.

...

Hi Pete,

thanks for the answer.

So

You are welcome Daniele and yes it appears as though you have it correct now.

Daniele Barell wrote:So double cannot get back to long because of the floating point

It cannot go back without losing precision, obviously. In general it can, you just need explicitly cast it to long.

Campbell, I may loose some point of your discourse:

I see.

But it's not a requirement. I mean I can use`x` without convert the literal to long:

OK

So why the compiler enables me to convert a long into double?

by the way, you are right:

I'm not a math wiz...What's the meaning of the last 'E18'?

Campbell Ritchie wrote:You are not using the number as a

long.1_000is anintliteral, which requires conversion to alongbefore you can use it. Thelongform of the number is1_000L.

I see.

But it's not a requirement. I mean I can use

Campbell Ritchie wrote:What PL has said is the explanation for a basic language requirement: a

doubleis regarded as a “wider” datatype that along, so you can implicitly widen one way, but you cannot convert the other way without a cast. As PL has hinted, the cast will lose any fractional part of the number.

OK

Campbell Ritchie wrote:You can also get loss of precision the other way; it is possible to fit 1234567891011121314L into a

long, but there is no guarantee that it can be exactly represented as adouble.

So why the compiler enables me to convert a long into double?

by the way, you are right:

I'm not a math wiz...What's the meaning of the last 'E18'?

Liutauras Vilda wrote:

Daniele Barell wrote:So double cannot get back to long because of the floating point

It cannot go back without losing precision, obviously. In general it can, you just need explicitly cast it to long.

Hi Liutaras,

thanks for the clarification!

Grammar lesson:

"long" is an adjective - describing the implied noun (integer)

"double" is also an adjective - describing the implied noun float (floating-point number, to be precise)

In computer grammar terms, the "adjectives" are called*modifiers.*

So you have 2 different base types and therefore not only does precision vary, but so does the domain of the representable number set.

I'd have to check, but I think that Java is one of the languages that also supports the construct "long double". The implied noun here is float, since upconversion makes floats of integers, so "double" is the determining word.

"long" is an adjective - describing the implied noun (integer)

"double" is also an adjective - describing the implied noun float (floating-point number, to be precise)

In computer grammar terms, the "adjectives" are called

So you have 2 different base types and therefore not only does precision vary, but so does the domain of the representable number set.

I'd have to check, but I think that Java is one of the languages that also supports the construct "long double". The implied noun here is float, since upconversion makes floats of integers, so "double" is the determining word.

That code has an implicit cast it. You have anDaniele Barell wrote:. . . I mean I can use

xwithout convert the literal to long:

Since the expression on the right is a constant expression, what many people call a compile‑time constant, the type conversion may be done by the compiler. If it is, it can be seen in the bytecode. You can view the bytecode with

If you scroll down a bit more, you will find there are also 22 “narrowing primitive conversions”. You will see from the example that they all require casts; if you attempt any of those conversions without a cast, the compiler must fail to accept the code, but the compiler error message about “possible loss of precision” isn't very clear.A widening primitive conversion from int to float, or from long to float, or from long to double, may result in loss of precision - that is, the result may lose some of the least significant bits of the value.

As it said earlier, “widening” conversions are always permitted.. . . So why the compiler enables me to convert a long into double? . . .

If you go back to the JLS link I gave above, you will see there are comments about range, saying that casting

Because you didn't specify any formatting, the output defaults to printing the fewest numbers necessary to identify the nearest distinct value. That turns out to be 1,234,567,890,101,114,100 but the default format is so‑called scientific format which on paper looks like 1.23456789101112141×10¹⁸, but older computers didn't have the pretty superscripts, so they write E18 instead of ×10¹⁸. Read that as meaning you move the decimal point 18 places to the right; in this case you will have to add a few 0s on the right.. . . What's the meaning of the last 'E18'?

If you are supposed to move the decimal point to the left, there will be a − after the E.

I am now going into hiding for embarrassment about how many posts I have

[edit]Additonal: I see that the 121314 at the right end of the number has turned into 14100 so the precision is worse than I thought. It also might mean that I have missed out a 0 at the right of the number I was discussing.

I'm not 100% certain about everything I'm about to assert because I'm going from IBM's floating-point specs and they are slightly different from the IEEE (Java ones). But here goes:

An integer is self-contained and it is at its heart a unitary value. A floating-point number is not. Floats have an exponent part and a mantissa part. The exponent scales the mantissa value. The mantissa is considered as a binary fraction - that is, 0.1 would have a value of 1/2. Given that, an exponent of 1 (meaning 2**1) and a mantissa of 0.100000000... would have an integral value of 1.

The difference between float, double and long double is primarily in the available amount of bit positions. The total bit occupancy of a float is 32 bits, a double is 64 bits and a long double is 128 bits.

Although, if memory serves, the IEEE spec does allow some extra bits for exponent values as well (IBM's S/360 version always had 8 bits for exponent and everything else was mantissa).

For a given number of exponent bits, adding bits to the overall value length does not increase the**range** of the number, but rather its **precision.** (also known as *epsilon.*). So downscaling from a double to a float, for example, would be the equivalent of chopping the value 9.3333333333 down to 9.333333. The approximate values are the same, but obviously not their exact values. Since the mantissa is a binary fraction and not a decimal one, a lot of decimal fractions are crude to begin with. 0.5 and 0.25 are easy (precise), but 0.1 is not (irrational, if I've got my terminology correct).

In the event that your floating-point system allows different-sized exponent bit allocations, downscaling where the target exponent cannot hold the original exponent value can potentially blow the number out of range. But in general, that should not result in infinity, but in a NaN value, since it's not literally infinity. And, of course raise a range exception.

So you have 2 vulnerabilities. First, that you will lose precision - downwards for positive numbers, upwards for negative numbers, and the loss of precision is not related to the related (nearest) integer value.

Secondly, that you will exceed the range of the integral reach of the number (exponent size).

Loss of precision is annoying, but non-fatal. Unless you accumulate enough erosion to, say, destroy an interplanetary exploration vehicle or steal from someone's paycheck. Loss of exponent range, on the other hand is an immediate problem, since it puts an immediate end to all further computation.

An integer is self-contained and it is at its heart a unitary value. A floating-point number is not. Floats have an exponent part and a mantissa part. The exponent scales the mantissa value. The mantissa is considered as a binary fraction - that is, 0.1 would have a value of 1/2. Given that, an exponent of 1 (meaning 2**1) and a mantissa of 0.100000000... would have an integral value of 1.

The difference between float, double and long double is primarily in the available amount of bit positions. The total bit occupancy of a float is 32 bits, a double is 64 bits and a long double is 128 bits.

Although, if memory serves, the IEEE spec does allow some extra bits for exponent values as well (IBM's S/360 version always had 8 bits for exponent and everything else was mantissa).

For a given number of exponent bits, adding bits to the overall value length does not increase the

In the event that your floating-point system allows different-sized exponent bit allocations, downscaling where the target exponent cannot hold the original exponent value can potentially blow the number out of range. But in general, that should not result in infinity, but in a NaN value, since it's not literally infinity. And, of course raise a range exception.

So you have 2 vulnerabilities. First, that you will lose precision - downwards for positive numbers, upwards for negative numbers, and the loss of precision is not related to the related (nearest) integer value.

Secondly, that you will exceed the range of the integral reach of the number (exponent size).

Loss of precision is annoying, but non-fatal. Unless you accumulate enough erosion to, say, destroy an interplanetary exploration vehicle or steal from someone's paycheck. Loss of exponent range, on the other hand is an immediate problem, since it puts an immediate end to all further computation.

I'm not sure if I approve of this interruption. But this tiny ad checks out:

Why should you try IntelliJ IDEA ?

https://coderanch.com/wiki/696337/IntelliJ-IDEA
This thread has been viewed 360 times.

All times above are in ranch (not your local) time.

The current ranch time is

Aug 17, 2018 03:57:12.

The current ranch time is

Aug 17, 2018 03:57:12.