Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #26504 > unrolled thread
| Started by | Michael Jung <miju@golem.phantasia.org> |
|---|---|
| First post | 2013-11-14 20:39 +0100 |
| Last post | 2013-11-17 08:05 -0800 |
| Articles | 11 — 7 participants |
Back to article view | Back to comp.lang.java.programmer
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: Possible loss of precision Michael Jung <miju@golem.phantasia.org> - 2013-11-14 20:39 +0100
Re: Possible loss of precision Gene Wirchenko <genew@telus.net> - 2013-11-14 15:03 -0800
Re: Possible loss of precision Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-11-14 18:31 -0500
Re: Possible loss of precision Joerg Meier <joergmmeier@arcor.de> - 2013-11-15 00:55 +0100
Re: Possible loss of precision Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-11-14 20:19 -0500
Re: Possible loss of precision taqmcg@gmail.com - 2013-11-15 07:01 -0800
Re: Possible loss of precision Martin Gregorie <martin@address-in-sig.invalid> - 2013-11-15 21:36 +0000
Re: Possible loss of precision Michael Jung <miju@golem.phantasia.org> - 2013-11-15 19:24 +0100
Re: Possible loss of precision Patricia Shanahan <pats@acm.org> - 2013-11-15 20:48 -0800
Re: Possible loss of precision Michael Jung <miju@golem.phantasia.org> - 2013-11-17 13:28 +0100
Re: Possible loss of precision Patricia Shanahan <pats@acm.org> - 2013-11-17 08:05 -0800
| From | Michael Jung <miju@golem.phantasia.org> |
|---|---|
| Date | 2013-11-14 20:39 +0100 |
| Subject | Re: Possible loss of precision |
| Message-ID | <87txfe22o1.fsf@golem.phantasia.org> |
ram@zedat.fu-berlin.de (Stefan Ram) writes: > char x = 'C' + 1; > x = x + 1; > in a block, one gets an error message > »possible loss of precision« > for »x = x + 1«. Ok, fair enough: »x + 1« has type »int«, > and precision is lost when assigning this to the variable x > of type char. > I was somewhat surprised, though, that »char x = 'C' + 1;« > does not yield an error, even though the type of »'C' + 1« > is int, too. Possibly, this time, the compiler can figure > out that the actual value still fits into a char. > But then, »int i = 2.0;« gives an error, even though the > compiler should see that »2.0« can be represented as an int. You are right that x+1 is "promoted" to int and the second assignment fails. In the other cases the compiler will follow JLS 15.28 => 5.2. This concerns constant expressions first and the second allows a narrowing in rare cases, of which the first line is one but the "int i = 2.0" isn't.
[toc] | [next] | [standalone]
| From | Gene Wirchenko <genew@telus.net> |
|---|---|
| Date | 2013-11-14 15:03 -0800 |
| Message-ID | <kkla89tv4vb3c60ao7qkj2hr3kd0ims4gc@4ax.com> |
| In reply to | #26504 |
On Thu, 14 Nov 2013 20:39:42 +0100, Michael Jung
<miju@golem.phantasia.org> wrote:
>ram@zedat.fu-berlin.de (Stefan Ram) writes:
>> char x = 'C' + 1;
>> x = x + 1;
>> in a block, one gets an error message
>> »possible loss of precision«
>> for »x = x + 1«. Ok, fair enough: »x + 1« has type »int«,
>> and precision is lost when assigning this to the variable x
>> of type char.
>> I was somewhat surprised, though, that »char x = 'C' + 1;«
>> does not yield an error, even though the type of »'C' + 1«
>> is int, too. Possibly, this time, the compiler can figure
>> out that the actual value still fits into a char.
>> But then, »int i = 2.0;« gives an error, even though the
>> compiler should see that »2.0« can be represented as an int.
>
>You are right that x+1 is "promoted" to int and the second assignment
>fails. In the other cases the compiler will follow JLS 15.28 => 5.2.
>This concerns constant expressions first and the second allows a
>narrowing in rare cases, of which the first line is one but the
>"int i = 2.0" isn't.
Why isn't it though?
Sincerely,
Gene Wirchenko
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2013-11-14 18:31 -0500 |
| Message-ID | <l63mh7$afg$1@dont-email.me> |
| In reply to | #26505 |
On 11/14/2013 6:03 PM, Gene Wirchenko wrote:
> On Thu, 14 Nov 2013 20:39:42 +0100, Michael Jung
> <miju@golem.phantasia.org> wrote:
>
>> ram@zedat.fu-berlin.de (Stefan Ram) writes:
>>> char x = 'C' + 1;
>>> x = x + 1;
>>> in a block, one gets an error message
>>> »possible loss of precision«
>>> for »x = x + 1«. Ok, fair enough: »x + 1« has type »int«,
>>> and precision is lost when assigning this to the variable x
>>> of type char.
>>> I was somewhat surprised, though, that »char x = 'C' + 1;«
>>> does not yield an error, even though the type of »'C' + 1«
>>> is int, too. Possibly, this time, the compiler can figure
>>> out that the actual value still fits into a char.
>>> But then, »int i = 2.0;« gives an error, even though the
>>> compiler should see that »2.0« can be represented as an int.
>>
>> You are right that x+1 is "promoted" to int and the second assignment
>> fails. In the other cases the compiler will follow JLS 15.28 => 5.2.
>> This concerns constant expressions first and the second allows a
>> narrowing in rare cases, of which the first line is one but the
>> "int i = 2.0" isn't.
>
> Why isn't it though?
Speculation: The fact that a floating-point expression happens
to evaluate to a number with no fractional part doesn't mean the
value "is" an integer. One reasonable view of FP is that a value
is just a representative of a range of real values, namely, all
those real values that round to the representative. In this
view, converting 2.0 to 2 *does* lose precision, specifically,
the amount of wiggle room.
Then again, maybe the Java designers were just FP-wary.
--
Eric Sosman
esosman@comcast-dot-net.invalid
[toc] | [prev] | [next] | [standalone]
| From | Joerg Meier <joergmmeier@arcor.de> |
|---|---|
| Date | 2013-11-15 00:55 +0100 |
| Message-ID | <nnts78v1vsvu.ew4fz8qb7bhm$.dlg@40tude.net> |
| In reply to | #26506 |
On Thu, 14 Nov 2013 18:31:53 -0500, Eric Sosman wrote: > On 11/14/2013 6:03 PM, Gene Wirchenko wrote: >> On Thu, 14 Nov 2013 20:39:42 +0100, Michael Jung >> <miju@golem.phantasia.org> wrote: >>> You are right that x+1 is "promoted" to int and the second assignment >>> fails. In the other cases the compiler will follow JLS 15.28 => 5.2. >>> This concerns constant expressions first and the second allows a >>> narrowing in rare cases, of which the first line is one but the >>> "int i = 2.0" isn't. >> Why isn't it though? > Speculation: The fact that a floating-point expression happens > to evaluate to a number with no fractional part doesn't mean the > value "is" an integer. One reasonable view of FP is that a value > is just a representative of a range of real values, namely, all > those real values that round to the representative. In this > view, converting 2.0 to 2 *does* lose precision, specifically, > the amount of wiggle room. My instinctive mental reply was that 2.0 instead of 2 is an explicit instruction to use double, much like L or F, which you wouldn't want to be silently ignored. Liebe Gruesse, Joerg -- Ich lese meine Emails nicht, replies to Email bleiben also leider ungelesen.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2013-11-14 20:19 -0500 |
| Message-ID | <l63sqt$9bm$1@dont-email.me> |
| In reply to | #26506 |
On 11/14/2013 6:31 PM, Eric Sosman wrote:
> On 11/14/2013 6:03 PM, Gene Wirchenko wrote:
>> On Thu, 14 Nov 2013 20:39:42 +0100, Michael Jung
>> <miju@golem.phantasia.org> wrote:
>>
>>> ram@zedat.fu-berlin.de (Stefan Ram) writes:
>>>> char x = 'C' + 1;
>>>> x = x + 1;
>>>> in a block, one gets an error message
>>>> »possible loss of precision«
>>>> for »x = x + 1«. Ok, fair enough: »x + 1« has type »int«,
>>>> and precision is lost when assigning this to the variable x
>>>> of type char.
>>>> I was somewhat surprised, though, that »char x = 'C' + 1;«
>>>> does not yield an error, even though the type of »'C' + 1«
>>>> is int, too. Possibly, this time, the compiler can figure
>>>> out that the actual value still fits into a char.
>>>> But then, »int i = 2.0;« gives an error, even though the
>>>> compiler should see that »2.0« can be represented as an int.
>>>
>>> You are right that x+1 is "promoted" to int and the second assignment
>>> fails. In the other cases the compiler will follow JLS 15.28 => 5.2.
>>> This concerns constant expressions first and the second allows a
>>> narrowing in rare cases, of which the first line is one but the
>>> "int i = 2.0" isn't.
>>
>> Why isn't it though?
>
> Speculation: The fact that a floating-point expression happens
> to evaluate to a number with no fractional part doesn't mean the
> value "is" an integer. One reasonable view of FP is that a value
> is just a representative of a range of real values, namely, all
> those real values that round to the representative. In this
> view, converting 2.0 to 2 *does* lose precision, specifically,
> the amount of wiggle room.
As a more concrete example,
static final double FOO = 17.316;
static final double BAR = 8.658;
int i = FOO / BAR; // Should javac be silent here?
Neither the numerator nor the denominator can be represented
exactly as stated, yet the quotient is (probably; cook up your
own numbers if mine are faulty) exactly 2.0. Would it be a
good idea to let this construct slide through unremarked? Or
should javac acknowledge the inherent imprecisions in the
operations leading to the exactly-integral result?
--
Eric Sosman
esosman@comcast-dot-net.invalid
[toc] | [prev] | [next] | [standalone]
| From | taqmcg@gmail.com |
|---|---|
| Date | 2013-11-15 07:01 -0800 |
| Message-ID | <4a561493-66cd-44c0-839a-542d752c405c@googlegroups.com> |
| In reply to | #26508 |
On Thursday, November 14, 2013 8:19:27 PM UTC-5, Eric Sosman wrote: > On 11/14/2013 6:31 PM, Eric Sosman wrote: > > As a more concrete example, > > static final double FOO = 17.316; > static final double BAR = 8.658; > int i = FOO / BAR; // Should javac be silent here? > > Neither the numerator nor the denominator can be represented > exactly as stated, yet the quotient is (probably; cook up your > own numbers if mine are faulty) exactly 2.0. Would it be a > good idea to let this construct slide through unremarked? Or > should javac acknowledge the inherent imprecisions in the > operations leading to the exactly-integral result? In this case it's pretty clear that the error should be signaled since we have a floating point expression that involves computations where roundoff's could do weird things: Consider the case when we use FOO = 3.3 and BAR = 1.1. Then the value of (int) (FOO/BAR) == 2 and I certainly wouldn't want to have a language where int i = 3.3/1.1; gives a different result than double x = 3.3; double y = 1.1; int i = x/y; When the integer value of the ration is a power of 2, then the internal floating point representations will differ only in the exponent, so you're likely get 'correct' values when you do the computation, but for all other integer ratios the actual value that a proper Java program would computer will often differ from the 'correct' value. And even for powers of two one is going to run into problems if denormalized floats or doubles are being used. If we exclude expressions there would be still hard cases: E.g., if we were allowing int i = 2.0; presumably we'd also want to allow int i = 1.234E3; // = 1234) but then you might be surprised to get an error for the equivalent int i = 1.2345E3; // = 1234.5 which doesn't really look very differnt. And what would one do with: int i = 123456789.f; which seems like a normal integer, but since we've gone beyond the precision of floats we'd find that float f = 123456789.f; int i = (int) f; yields i == 123456792 We wouldn't run into this when converting doubles to ints, but a similar problem occurs for doubles to longs. So any relaxation of the rule that there is a loss-of-precision error in converting floating point values to integral values would have to be either arbitrarily limited (say to |integers| < 100) or hedged with lots of caveats. Having a simple rule that you need to signal such a conversion with a cast seems like a reasonable choice. Personally I'd have preferred that Java be fully consistent here and not have the exception for operators like += double x = 1.; int i = 0; i += x; // is legal but I believe that exception is essentially required by the (imho) folly of automatic promotion of bytes, shorts and chars to ints. Regards, Tom McGlynn
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2013-11-15 21:36 +0000 |
| Message-ID | <l66447$qat$1@dont-email.me> |
| In reply to | #26508 |
On Thu, 14 Nov 2013 20:19:27 -0500, Eric Sosman wrote:
> Neither the numerator nor the denominator can be represented exactly as
> stated, yet the quotient is (probably; cook up your own numbers if mine
> are faulty) exactly 2.0. Would it be a good idea to let this construct
> slide through unremarked? Or should javac acknowledge the inherent
> imprecisions in the operations leading to the exactly-integral result?
>
I think Java is weak in this area - the ancient Algol68 language did this
better with its explicit concept of widening and narrowing numbers
int n;
float f;
double d;
d = f; d = n; f = n;
are all examples of widening, and all are legal as you'd expect because
there is no loss of precision, while
n = f; n = d; f = d;
are all examples of narrowing, which involves loss of precision, and so
are rejected by the compiler, which forces you to use a conversion
function, such as round(), floor() or ceil(). Compared with this, using a
cast to narrow a number is a very blunt instrument.
The standard A68 library overloaded these functions so they worked
correctly between all numeric types including, IIRC, that you could use
them to convert and numeric type to or from a bool.
The odd thing is that all Java need to fix this is to extend the Math
class with the appropriate methods.
--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |
[toc] | [prev] | [next] | [standalone]
| From | Michael Jung <miju@golem.phantasia.org> |
|---|---|
| Date | 2013-11-15 19:24 +0100 |
| Message-ID | <87txfded5c.fsf@golem.phantasia.org> |
| In reply to | #26505 |
Gene Wirchenko <genew@telus.net> writes: > On Thu, 14 Nov 2013 20:39:42 +0100, Michael Jung > <miju@golem.phantasia.org> wrote: >>ram@zedat.fu-berlin.de (Stefan Ram) writes: [...] >>> But then, »int i = 2.0;« gives an error, even though the >>> compiler should see that »2.0« can be represented as an int. >>You are right that x+1 is "promoted" to int and the second assignment >>fails. In the other cases the compiler will follow JLS 15.28 => 5.2. >>This concerns constant expressions first and the second allows a >>narrowing in rare cases, of which the first line is one but the >>"int i = 2.0" isn't. > Why isn't it though? Since compile-time constant expressions are FP-strict and could be done, I guess it was seen as pathological and not worth the effort. Michael
[toc] | [prev] | [next] | [standalone]
| From | Patricia Shanahan <pats@acm.org> |
|---|---|
| Date | 2013-11-15 20:48 -0800 |
| Message-ID | <1cydnYUCtYikZBvPnZ2dnUVZ_umdnZ2d@earthlink.com> |
| In reply to | #26513 |
On 11/15/2013 10:24 AM, Michael Jung wrote: > Gene Wirchenko <genew@telus.net> writes: >> On Thu, 14 Nov 2013 20:39:42 +0100, Michael Jung >> <miju@golem.phantasia.org> wrote: >>> ram@zedat.fu-berlin.de (Stefan Ram) writes: > [...] >>>> But then, »int i = 2.0;« gives an error, even though the >>>> compiler should see that »2.0« can be represented as an int. >>> You are right that x+1 is "promoted" to int and the second assignment >>> fails. In the other cases the compiler will follow JLS 15.28 => 5.2. >>> This concerns constant expressions first and the second allows a >>> narrowing in rare cases, of which the first line is one but the >>> "int i = 2.0" isn't. >> Why isn't it though? > > Since compile-time constant expressions are FP-strict and could be done, > I guess it was seen as pathological and not worth the effort. I think the difference is that there is a cast-free way of initializing an int to the value 2. On the other hand, without the special narrowing rule for initializers, there would be no cast-free way of initializing a byte with the value 2. Patricia
[toc] | [prev] | [next] | [standalone]
| From | Michael Jung <miju@golem.phantasia.org> |
|---|---|
| Date | 2013-11-17 13:28 +0100 |
| Message-ID | <878uwnw6t1.fsf@golem.phantasia.org> |
| In reply to | #26516 |
Patricia Shanahan <pats@acm.org> writes: > On 11/15/2013 10:24 AM, Michael Jung wrote: >> Gene Wirchenko <genew@telus.net> writes: >>> On Thu, 14 Nov 2013 20:39:42 +0100, Michael Jung >>> <miju@golem.phantasia.org> wrote: >>>> ram@zedat.fu-berlin.de (Stefan Ram) writes: >> [...] >>>>> But then, »int i = 2.0;« gives an error, even though the >>>>> compiler should see that »2.0« can be represented as an int. >>>> You are right that x+1 is "promoted" to int and the second assignment >>>> fails. In the other cases the compiler will follow JLS 15.28 => 5.2. >>>> This concerns constant expressions first and the second allows a >>>> narrowing in rare cases, of which the first line is one but the >>>> "int i = 2.0" isn't. >>> Why isn't it though? >> Since compile-time constant expressions are FP-strict and could be done, >> I guess it was seen as pathological and not worth the effort. > I think the difference is that there is a cast-free way of > initializing an int to the value 2. Not if you wanted to do "int a = 2 * 0.5;" or something similar. > On the other hand, without the special narrowing rule for > initializers, there would be no cast-free way of initializing a byte > with the value 2. They could have spent a suffix "B/b" (for non-hex integer literals) as with "l/L". Michael
[toc] | [prev] | [next] | [standalone]
| From | Patricia Shanahan <pats@acm.org> |
|---|---|
| Date | 2013-11-17 08:05 -0800 |
| Message-ID | <8pqdnQaCOuvddBXPnZ2dnUVZ_oSdnZ2d@earthlink.com> |
| In reply to | #26523 |
On 11/17/2013 4:28 AM, Michael Jung wrote: > Patricia Shanahan <pats@acm.org> writes: ... >> On the other hand, without the special narrowing rule for >> initializers, there would be no cast-free way of initializing a byte >> with the value 2. > > They could have spent a suffix "B/b" (for non-hex integer literals) as > with "l/L". Why non-hex? You would still need something like the current system for hex initialization of a byte. The would have needed to do the the same for short, [-32768, 32767], and for numeric initializers for char, [0, 65535]. Patricia
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web