Velocity Reviews > Re: Unexpected truncation behavior

# Re: Unexpected truncation behavior

88888 Dihedral
Guest
Posts: n/a

 06-29-2013
Giuseppe於 2013年6月28日星期五UTC+8下午7時14分09秒 寫道：
> Il 28/06/2013 13:11, Kenny McCormack ha scritto:
>
>
>
> >

>
> > The stock clc answer is: It doesn't matter what happens. Anything can

>
> > happen. It is just as likely to depend on the phase of the moon as it is

>
> > to depend on the OS or the compiler in use.

>
> >

>
> > As far as I can tell, C is perfectly free to report the result of:

>
> >

>
> > 2.1 + 3.4

>
> >

>
> > as

>
> >

>
> > 9.76

>
> >

>
>
>
> So you are saying that we cannot do calculations with the C language?
>
>
>
> --
>
> Giuseppe

OK, I was got paid well in writing C and assembly programs
to do non-trivial computations.

But if I am not paid enough, I'll just write and give some
short scripts away as tips.

Eric Sosman
Guest
Posts: n/a

 06-29-2013
On 6/29/2013 8:09 AM, Dr Nick wrote:
> Eric Sosman <(E-Mail Removed)> writes:
> [...] Using paper and
>> pencil and ordinary decimal arithmetic, try calculating the sum
>> of one-seventh, three-sevenths, and three-sevenths.[...]
>>
>> - 0.1 + 0.4 + 0.4 = 0.9, too low
>> - 0.14 + 0.43 + 0.43 = 1.00, spot on
>> - 0.143 + 0.429 + 0.429 = 1.001, too high
>> - 0.1429 + 0.4286 + 0.4286 = 1.0001, too high again
>> - 0.14286 + 0.42857 + 0.42857 = 1.00000, exact again
>> - 0.142857 + 0.428571 + 0.428571 = 0.999999, too low again
>> [...]

>
> When rounded to the nearest integer, the third row gives the "right"
> answer and the last the "wrong" answer. That could be described as
> "more accurate", but it's not - it's an effect of the rounding: the last
> is actually closer to the real answer.

ITYM "truncated" rather than "rounded to the nearest integer."
All six sums round to 1, and are then equally (perfectly) accurate.
If you *don't* mean "truncated" then you've lost me, and I hope
you'll explain further.

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)d

Stephen Sprunk
Guest
Posts: n/a

 06-29-2013
On 28-Jun-13 09:23, Giuseppe wrote:
> I just tried again and this is what happens: the build of gcc I have
> on Windows doesn't optimize code by default. I have to enable -O1 at
> least to get r2==10 instead of 9. On Linux I get directly r2==10 and
> only get r2==9 if I disable optimizations with -O0.

So, basically, what you are seeing is that gcc -O0 gives r2==9 on both
platforms and gcc -O1 gives r2=10 on both platforms. So, the "problem"
has nothing to do with the platform and everything to do with the gcc
optimization level used.

It's well-known that gcc -O0 generates amazingly stupid code, storing
all variables to memory after assignment and then retrieving them again
for the next use--even if it's the very next statement--rather than
keeping them in registers. For integer code, this is inefficient but
shouldn't cause the result to change. x87 floating-point code, though,
is different: all values kept in registers have 80-bit precision, while
only "long double" variables have 80-bit precision in memory; if stored
to memory as float or double, they only have 32-bit or 64-bit precision,
which can cause results to change slightly--enough for truncation to
give much larger differences when converted to integers.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking

glen herrmannsfeldt
Guest
Posts: n/a

 06-30-2013
Stephen Sprunk <(E-Mail Removed)> wrote:

(snip)
> It's well-known that gcc -O0 generates amazingly stupid code, storing
> all variables to memory after assignment and then retrieving them again
> for the next use--even if it's the very next statement--rather than
> keeping them in registers. For integer code, this is inefficient but
> shouldn't cause the result to change. x87 floating-point code, though,
> is different: all values kept in registers have 80-bit precision, while
> only "long double" variables have 80-bit precision in memory; if stored
> to memory as float or double, they only have 32-bit or 64-bit precision,
> which can cause results to change slightly--enough for truncation to
> give much larger differences when converted to integers.

Change those to 64, 24, and 53, respectively.

-- glen