[Cryptography] floating point

John Denker jsd at av8n.com
Wed Dec 24 01:39:34 EST 2014

On 12/23/2014 09:15 PM, Jerry Leichter wrote:

> [...] "never print more digits of precision than your floating point
>  numbers can actually represent" is one way of getting at it. 
> Following this rule avoids all kinds of traps people fall into when 
> they think they can get more precision out of a calculation than the
>  numbers themselves can actually carry.  Seen it happen....

That's just completely backwards.  If you want to roundtrip a
number -- i.e. write it back out and read it back in, producing
the same internal representation -- it is quite likely that you
need to print /more/ digits than the internal representation
can handle.

Roundtripping IEEE double precision requires 17 decimal digits.
This is well known in numerical analysis circles.  See code below.

    Of course if you want to go the other direction, hairpinning
    an external number into the machine and back out again, the
    limiting number of digits is lower ... but that's the answer
    to a very different question.

> For most people who don't dig deeper, following the two rules "Don't
> compare floating values for equality" and "don't subtract floating
> values that are very close to each other" will avoid many of the
> common traps of floating point.

Perhaps the people who don't care enough about the subject to
dig beyond one-sentence slogans should refrain from sneering 
at people who do.

#! /usr/bin/perl -w

use POSIX qw/ceil/;

# Returns the lowest safe upper bound on the number of
# decimal digits to guarantee that writing a number and
# reading it back in produces the same internal
# representation.
# Obviously we can only provide an upper bound; /sometimes/
# you can get away with something much lower, perhaps a
# single digit.
sub roundtrip_decimal_digs{
  my ($internal_radix, $internal_digits) = @_;
  $pack = log($internal_radix) / log(10);       # packing factor
  return ceil($pack*$internal_digits) + ($pack==int($pack)? 0:1)

print roundtrip_decimal_digs(2, 53), "\n";     # for IEEE double precision

More information about the cryptography mailing list