Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #139029

Re: A final word on casting.

Subject Re: A final word on casting.
Newsgroups comp.lang.c
References (4 earlier) <875zvki950.fsf@bsb.me.uk> <fabc96a8-762e-430e-a567-8658f60fe0d5@googlegroups.com> <QdOTD.34006$Ck1.30728@fx18.am4> <pJRTD.94984$gU6.40605@fx33.iad> <a6u12et49jgehl4ont9shhj521me5h3k2j@4ax.com>
From Richard Damon <Richard@Damon-Family.org>
Message-ID <1J9UD.115584$4d4.8940@fx41.iad> (permalink)
Organization Forte - www.forteinc.com
Date 2018-12-24 13:38 -0500

Show all headers | View raw


On 12/24/18 10:39 AM, Robert Wessel wrote:
> On Sun, 23 Dec 2018 14:53:57 -0500, Richard Damon
> <Richard@Damon-Family.org> wrote:
> 
>> On 12/23/18 10:55 AM, Bart wrote:
>>> On 23/12/2018 15:08, chanrasjid@gmail.com wrote:
>>>> On Sunday, December 23, 2018 at 10:57:14 PM UTC+8, Ben Bacarisse wrote:
>>>>> Bart <bc@freeuk.com> writes:
>>>>>
>>>>>> On 23/12/2018 13:08, Ben Bacarisse wrote:
>>>>>>> Bart <bc@freeuk.com> writes:
>>>>>>
>>>>>>>> Try:
>>>>>>>>
>>>>>>>> printf("%d\n", (int)1.9999999999999999999999999999999);
>>>>>>>>
>>>>>>>> I seem to get the answer 2.
>>>>>>>
>>>>>>> Are you really puzzled by that?
>>>>>>
>>>>>> Actually, yes. It means that (int)1.something will usually be 1 but
>>>>>> sometimes 2.
>>>>>
>>>>> At least you won't be puzzled any more.
>>>
>>> Don't be so sure.
>>>
>>>> I think it is reasonable. C gives the closest double to represent
>>>> 1.999... and it is 2.0; So (int) x gives the integral part is "almost"
>>>> official.
>>>
>>> How does "1.999999999999..." in source code end up as /exactly/ 2.0?
>>>
>>> Try this program, which starts from 1.0 then successively ends 0.9,
>>> 0.09, 0.009 etc to get progressively longer versions of 1.999...
>>>
>>> It gets closer and closer to 2.0, but is never exactly 2.0:
>>>
>>>   #include <stdio.h>
>>>
>>>   int main (void) {
>>>     double a,b;
>>>
>>>     a=1.0;
>>>     b=0.9;
>>>     for (int i=0; i<30; ++i) {
>>>         a+=b;
>>>         printf("a: %.24f, 2.0-a: %.10e, a%s2.0, (int)a: %d, b: %e\n",
>>>              a, 2.0-a, (a==2.0?"==":"!="), (int)a, b);
>>>         b/=10.0;
>>>     }
>>>   }
>>>
>>> So it appears to be either rounding deliberately applied by a C
>>> compiler, or a side-effect of how the calculation is actually done.
>>>
>>
>> One issue is that by the standard, to achieve the specified accuracy,
>> the implementation isn't allowed to just simply get the value of the
>> places with a chain of multiplication by 0.1 (or division by 10.0), as
>> that may build up too much accumulated error (and the difference between
>> 2.0 and the number just below it is a very small number, so tiny errors
>> might be important).
>>
>> Instead I would expect something more like:
>>
>> int main(void) {
>>   double a, b, c;
>>   a = 1.0;
>>   b = 1.0;
>>   for(int i = 0; i < 30; i++) {
>>      a = 10 * a + 9;
>>      b = 10 * b;
>>      c = a/b;
>>      printf("c: %.24f, 2.0-c: %.10e,  c$s2.0, (int)c: %d b:%e\n",
>>         c, 2.0-c, (c == 2.0) ? "==" : "!=", (int) c, b);
>>   }
>> }
>>
>> Since a and b will always hold an 'integral' value, until their
>> magnitude exceeds the precision that can be stored in a double, the only
>> round off will be in computing a/b
> 
> 
> That is the usual approach.  It also produces the strictest results
> (the representable number closest to the literal) assuming that the
> division operations follows that rule (any IEEE compliant FP
> implementation will do so, but there have certainty been machines
> where that's not the case).
> 
> The usual limit is when the numerator exceeds the available precision
> of a double.  The denominator is usually not the problem, since it
> always contains a fair-sized power of two as a factor (and on binary
> FP systems, that doesn't consume mantissa bits).
> 
> If you need to maintain high accuracy beyond that, it becomes more
> challenging, although the above never really goes more than a couple
> of ULPs astray until the input string gets considerably longer than
> the nominal precision of a double.  I suspect that in many cases
> people have just ignored that.
> 
> But...  you can divide the number into sections, each no wider than
> the available precision.  Then you can compute both the quotient and
> rounding error for each section, and then work your way across
> determining if the rounding error (roughly the remainder, slightly
> cooked) for one section, plus the quotient for the next section
> (possibly post-rounding correction itself), requires an increment in
> the first section.  That usually requires at least some understanding
> of the FP model in use.  You can use a similar approach to produce
> accurate results on machines where division produces questionable
> quotients.
> 
> Other approaches are possible as well.  A simple, if slow, one is to
> compute that with a bignum library, and then convert a (binary) scaled
> quotient to the FP value.  That will still require a rounding
> adjustment, but it's easy to pick out of the remainder of the bignum
> division.
> 

If the goal is to convert a string to a double value, you can basically
stop when the numerator goes by the precision limit, as additional terms
can't really affect the final result (maybe affect which way would be
the preferred way to round). You could perhaps even do better
accumulating the values into an int64_t (if your double is 64 bits) and
then at the end convert and divide or convert while dividing, but in
this case you MUST terminate the accumulation before you overflow the 64
bit int.

If you want a higher precision result, you of course need a higher
precision accumulator (maybe int128_t or a bignum) and a higher
precision output format.

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

A final word on casting. chanrasjid@gmail.com - 2018-12-23 03:02 -0800
  Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-23 12:11 +0000
    Re: A final word on casting. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-12-23 13:08 +0000
      Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-23 14:43 +0000
        Re: A final word on casting. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-12-23 14:56 +0000
          Re: A final word on casting. chanrasjid@gmail.com - 2018-12-23 07:08 -0800
            Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-23 15:55 +0000
              Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-23 16:07 +0000
              Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-12-23 08:21 -0800
              Re: A final word on casting. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-12-23 17:56 +0000
                Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-23 19:23 +0000
                Re: A final word on casting. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-12-23 20:12 +0000
                Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-12-23 14:06 -0800
                Re: A final word on casting. Tim Rentsch <txr@alumni.caltech.edu> - 2018-12-28 09:34 -0800
                Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-28 20:29 +0000
                Re: A final word on casting. Tim Rentsch <txr@alumni.caltech.edu> - 2018-12-28 15:07 -0800
                Re: A final word on casting. Richard Damon <Richard@Damon-Family.org> - 2018-12-28 20:56 -0500
                Re: A final word on casting. Tim Rentsch <txr@alumni.caltech.edu> - 2018-12-29 09:22 -0800
                Re: A final word on casting. Tim Rentsch <txr@alumni.caltech.edu> - 2019-01-01 13:27 -0800
                Re: A final word on casting. Bart <bc@freeuk.com> - 2019-01-02 01:07 +0000
                Re: A final word on casting. Bart <bc@freeuk.com> - 2019-01-03 18:55 +0000
                Re: A final word on casting. Richard Damon <Richard@Damon-Family.org> - 2019-01-03 22:27 -0500
                Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-01-04 16:25 -0500
                Re: A final word on casting. Ike Naar <ike@iceland.freeshell.org> - 2018-12-28 19:10 +0000
                Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-12-28 12:33 -0800
                Re: A final word on casting. "Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid> - 2018-12-23 14:11 -0800
                Re: A final word on casting. Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-12-24 02:54 -0800
                Re: A final word on casting. fir <profesor.fir@gmail.com> - 2018-12-24 03:24 -0800
                Re: A final word on casting. fir <profesor.fir@gmail.com> - 2018-12-24 03:29 -0800
                Re: A final word on casting. fir <profesor.fir@gmail.com> - 2018-12-24 03:45 -0800
                Re: A final word on casting. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-12-24 13:44 +0000
                Re: A final word on casting. Richard Damon <Richard@Damon-Family.org> - 2018-12-24 08:51 -0500
              Re: A final word on casting. Richard Damon <Richard@Damon-Family.org> - 2018-12-23 14:53 -0500
                Re: A final word on casting. Robert Wessel <robertwessel2@yahoo.com> - 2018-12-24 09:39 -0600
                Re: A final word on casting. Richard Damon <Richard@Damon-Family.org> - 2018-12-24 13:38 -0500
              Re: A final word on casting. Manfred <noname@add.invalid> - 2018-12-23 21:22 +0100
              Re: A final word on casting. Manfred <noname@add.invalid> - 2018-12-23 21:33 +0100
            Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-12-23 10:56 -0500
              Re: A final word on casting. Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> - 2018-12-23 17:18 +0100
        Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-23 20:03 +0000
    Re: A final word on casting. "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2018-12-28 14:47 -0500
  Re: A final word on casting. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-12-23 12:24 +0000
  Re: A final word on casting. Richard Damon <Richard@Damon-Family.org> - 2018-12-23 07:28 -0500
    Re: A final word on casting. Tim Rentsch <txr@alumni.caltech.edu> - 2018-12-28 07:50 -0800
  Re: A final word on casting. fir <profesor.fir@gmail.com> - 2018-12-23 04:35 -0800
    Re: A final word on casting. fir <profesor.fir@gmail.com> - 2018-12-23 04:42 -0800
      Re: A final word on casting. fir <profesor.fir@gmail.com> - 2018-12-23 04:52 -0800
  Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-12-23 10:28 -0500
  Re: A final word on casting. Barry Schwarz <schwarzb@dqel.com> - 2018-12-23 11:39 -0800
    Re: A final word on casting. Ike Naar <ike@iceland.freeshell.org> - 2018-12-24 07:56 +0000
  Re: A final word on casting. chanrasjid@gmail.com - 2018-12-24 14:03 -0800
    Re: A final word on casting. Barry Schwarz <schwarzb@dqel.com> - 2018-12-24 14:39 -0800
      Re: A final word on casting. chanrasjid@gmail.com - 2018-12-24 14:50 -0800
        Re: A final word on casting. Keith Thompson <kst-u@mib.org> - 2018-12-24 15:34 -0800
      Re: A final word on casting. Keith Thompson <kst-u@mib.org> - 2018-12-24 15:23 -0800
        Re: A final word on casting. chanrasjid@gmail.com - 2018-12-24 20:34 -0800
    Re: A final word on casting. Keith Thompson <kst-u@mib.org> - 2018-12-24 14:52 -0800
      Re: A final word on casting. chanrasjid@gmail.com - 2018-12-24 20:25 -0800
    Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-12-24 17:52 -0500
    Re: A final word on casting. luser droog <luser.droog@gmail.com> - 2018-12-24 21:27 -0800
      Re: A final word on casting. luser droog <luser.droog@gmail.com> - 2018-12-24 21:39 -0800
      Re: A final word on casting. chanrasjid@gmail.com - 2018-12-24 22:36 -0800

csiph-web