1. Perl
  2. Numerical value
  3. Error

Numerical values and errors

Error is a problem when expressing decimal numbers on a computer. Decimal numbers that cannot be expressed in binary will have an error.

Computers can only represent numbers internally as binary numbers. Any number can be expressed as a binary number for integers.

The problem is decimals. The minority that can be expressed in binary is numbers expressed in 1/2 nth root such as 0.5, 0.25, 0.125, 0.0625 (in order, 1/2, 1/4, 1/8, 1/16) and these. Only the number represented by the sum of (for example, 0.75).

0.3 is not an integer no matter how much you multiply it by 2, so it cannot be expressed accurately in binary. Computers manage by approximating such numbers. 0.3 is approximated using binary numbers as follows:

0.3 = 1/4 + 1/32 + 1/64 + 1/512
= 0.25 + 0.03125 + 0.015625 + 0.001953125
= 0.298828125

By adding smaller binary numbers in this way, the approximate value can be made closer to the actual value. Still, it is never equal to the actual value of 0.3. (Only in the world of mathematics dealing with the limit is equal to 0.3. In finite addition in the real world, it is not equal to 0.3.)

In this way, computers always have an error when dealing with numbers other than those that can be represented by the sum of binary numbers.

1 and 0.1 added 10 times are different

1 can be expressed as a binary number. On the other hand, 0.1 cannot be expressed in binary. In the computer world, 0.1 is not a true 0.1, but an approximation of 0.1. Therefore, adding 0.1 10 times does not result in 1.

You need to be careful when comparing numbers when dealing with decimal numbers. How to compare decimal numbers will be described later.

Example

This is an example to check the occurrence of error.

use strict;
use warnings;

# 1/4 Can be expressed in binary numbers.
my $num1 = 0.25;

# 1/2 + 1/4 Can be expressed in binary.
my $num2 = 0.625;

# In binary, it can only be expressed as an approximate value.
my $num3 = 0.3;

print "(1) Binary numbers that cannot be represented\are approximate values.\n";
printf("\$num1 = %.60f\n", $num1);
printf("\$num2 = %.60f\n", $num2);

# It does not become 0.3.
printf("\$num3 = %.60f\n", $num3);
print "\n";

my $num4 = 1;
my $num5;

# If you add 0.1 10 times, you should get 1, but that's not the case.
for my $i (1 .. 10) {
  $num5 += 0.1;
}

print "(2) The value obtained by adding 1 and 0.1 10 times is different.\n";
if ($num4 == $num5) {
  print "\$num4 and \$num5 are equal.\n";
}
else {
  print "\$num4 and \$num5 are not equal.\n";
  printf("\$num4 = %.60f\n", $num4);
  printf("\$num5 = %.60f\n", $num5);
}

(Reference) printf function

Related Informatrion