# A little bug, I don't know why

I've just made a program which:
- reads n > 0 (let's say it 61589)
- assigns each numeral of n to an array (m)

that means
m[1]= 9 = n mod 10
m[2]= 8 = ( (n mod 10^2) - m[1] ) /10
m[3]= 5 = ( (n mod 10^3) - m[2] ) /10^2
m[4]= 1 = ( (n mod 10^4) - m[3] ) /10^3
m[5]= 6 = ( (n mod 10^5) - m[4] ) /10^4

as you can see, the rule is apparent:

m[i]= ( (n mod 10^i) - m[i-1] ) / 10^(i-1)

(with m[0]=0)

And in Pascal, we have:
10^i = exp(i*ln(10))

then the formula becomes:

m[i]= ( ( n mod trunc(exp(i*ln(10))) ) - m[i-1] ) / exp((i-1)*ln(10))

The problem is, when execute that code, some of the m[i] are not round, I don't know if there's an error in my code, and I'm stuck with it

Here's the code, run it, and you'll see

[code]
program test;
uses crt;

var l,i:integer;
m:array[0..255] of real;
n:longint;
st:string;

begin
clrscr;
str(n,st); {convert n to string}
l:=length(st); {and get its length}
m[0]:=0;
for i:=1 to l do
begin
m[i]:=((n mod (trunc(exp(i*ln(10)))))-m[i-1])/(exp((i-1)*ln(10))); {?????}
writeln(m[i]);
end;
writeln
writeln('Length of n = ',l);
writeln;writeln('Enter to end');
end.
[/code]

can anybody find the reason?

• : I've just made a program which:
: - reads n > 0 (let's say it 61589)
: - assigns each numeral of n to an array (m)
:
: that means
: m[1]= 9 = n mod 10
: m[2]= 8 = ( (n mod 10^2) - m[1] ) /10
: m[3]= 5 = ( (n mod 10^3) - m[2] ) /10^2
: m[4]= 1 = ( (n mod 10^4) - m[3] ) /10^3
: m[5]= 6 = ( (n mod 10^5) - m[4] ) /10^4
:
: as you can see, the rule is apparent:
:
: m[i]= ( (n mod 10^i) - m[i-1] ) / 10^(i-1)
:
: (with m[0]=0)
:
: And in Pascal, we have:
: 10^i = exp(i*ln(10))
:
: then the formula becomes:
:
: m[i]= ( ( n mod trunc(exp(i*ln(10))) ) - m[i-1] ) / exp((i-1)*ln(10))
:
: The problem is, when execute that code, some of the m[i] are not round, I don't know if there's an error in my code, and I'm stuck with it
:
: Here's the code, run it, and you'll see
:
: [code]
: program test;
: uses crt;
:
: var l,i:integer;
: m:array[0..255] of real;
: n:longint;
: st:string;
:
: begin
: clrscr;
: str(n,st); {convert n to string}
: l:=length(st); {and get its length}
: m[0]:=0;
: for i:=1 to l do
: begin
: m[i]:=((n mod (trunc(exp(i*ln(10)))))-m[i-1])/(exp((i-1)*ln(10))); {?????}
: writeln(m[i]);
: end;
: writeln
: writeln('Length of n = ',l);
: writeln;writeln('Enter to end');
: end.
: [/code]
:
: can anybody find the reason?
:
exp((i-1)*ln(10) = a double. Hence the whole division becomes a double. I myself would use a much simpler code:
[code]
for i := 1 to l do
m[i] := byte(st[l-i+1])-byte('0');
[/code]
This code converts each character in the string into the ASCII code, and then the ASCII of the 0-character is removed from it to make the values into 0 to 9.
• : : I've just made a program which:
: : - reads n > 0 (let's say it 61589)
: : - assigns each numeral of n to an array (m)
: :
: : that means
: : m[1]= 9 = n mod 10
: : m[2]= 8 = ( (n mod 10^2) - m[1] ) /10
: : m[3]= 5 = ( (n mod 10^3) - m[2] ) /10^2
: : m[4]= 1 = ( (n mod 10^4) - m[3] ) /10^3
: : m[5]= 6 = ( (n mod 10^5) - m[4] ) /10^4
: :
: : as you can see, the rule is apparent:
: :
: : m[i]= ( (n mod 10^i) - m[i-1] ) / 10^(i-1)
: :
: : (with m[0]=0)
: :
: : And in Pascal, we have:
: : 10^i = exp(i*ln(10))
: :
: : then the formula becomes:
: :
: : m[i]= ( ( n mod trunc(exp(i*ln(10))) ) - m[i-1] ) / exp((i-1)*ln(10))
: :
: : The problem is, when execute that code, some of the m[i] are not round, I don't know if there's an error in my code, and I'm stuck with it
: :
: : Here's the code, run it, and you'll see
: :
: : [code]
: : program test;
: : uses crt;
: :
: : var l,i:integer;
: : m:array[0..255] of real;
: : n:longint;
: : st:string;
: :
: : begin
: : clrscr;
: : str(n,st); {convert n to string}
: : l:=length(st); {and get its length}
: : m[0]:=0;
: : for i:=1 to l do
: : begin
: : m[i]:=((n mod (trunc(exp(i*ln(10)))))-m[i-1])/(exp((i-1)*ln(10))); {?????}
: : writeln(m[i]);
: : end;
: : writeln
: : writeln('Length of n = ',l);
: : writeln;writeln('Enter to end');
: : end.
: : [/code]
: :
: : can anybody find the reason?
: :
: exp((i-1)*ln(10) = a double. Hence the whole division becomes a double. I myself would use a much simpler code:
: [code]
: for i := 1 to l do
: m[i] := byte(st[l-i+1])-byte('0');
: [/code]
: This code converts each character in the string into the ASCII code, and then the ASCII of the 0-character is removed from it to make the values into 0 to 9.
:

Yes, your code is indeed simplier and wiser, but I want to know why the values are not round?
you said the division is a double, ok, but does this affect the result?

• : : : I've just made a program which:
: : : - reads n > 0 (let's say it 61589)
: : : - assigns each numeral of n to an array (m)
: : :
: : : that means
: : : m[1]= 9 = n mod 10
: : : m[2]= 8 = ( (n mod 10^2) - m[1] ) /10
: : : m[3]= 5 = ( (n mod 10^3) - m[2] ) /10^2
: : : m[4]= 1 = ( (n mod 10^4) - m[3] ) /10^3
: : : m[5]= 6 = ( (n mod 10^5) - m[4] ) /10^4
: : :
: : : as you can see, the rule is apparent:
: : :
: : : m[i]= ( (n mod 10^i) - m[i-1] ) / 10^(i-1)
: : :
: : : (with m[0]=0)
: : :
: : : And in Pascal, we have:
: : : 10^i = exp(i*ln(10))
: : :
: : : then the formula becomes:
: : :
: : : m[i]= ( ( n mod trunc(exp(i*ln(10))) ) - m[i-1] ) / exp((i-1)*ln(10))
: : :
: : : The problem is, when execute that code, some of the m[i] are not round, I don't know if there's an error in my code, and I'm stuck with it
: : :
: : : Here's the code, run it, and you'll see
: : :
: : : [code]
: : : program test;
: : : uses crt;
: : :
: : : var l,i:integer;
: : : m:array[0..255] of real;
: : : n:longint;
: : : st:string;
: : :
: : : begin
: : : clrscr;
: : : str(n,st); {convert n to string}
: : : l:=length(st); {and get its length}
: : : m[0]:=0;
: : : for i:=1 to l do
: : : begin
: : : m[i]:=((n mod (trunc(exp(i*ln(10)))))-m[i-1])/(exp((i-1)*ln(10))); {?????}
: : : writeln(m[i]);
: : : end;
: : : writeln
: : : writeln('Length of n = ',l);
: : : writeln;writeln('Enter to end');
: : : end.
: : : [/code]
: : :
: : : can anybody find the reason?
: : :
: : exp((i-1)*ln(10) = a double. Hence the whole division becomes a double. I myself would use a much simpler code:
: : [code]
: : for i := 1 to l do
: : m[i] := byte(st[l-i+1])-byte('0');
: : [/code]
: : This code converts each character in the string into the ASCII code, and then the ASCII of the 0-character is removed from it to make the values into 0 to 9.
: :
:
: Yes, your code is indeed simplier and wiser, but I want to know why the values are not round?
: you said the division is a double, ok, but does this affect the result?
:
:
Yes, because when you calculate with doubles the computer will make rounding errors. For example:
exp((i-1)*ln(10)) is about 10^(i-1), but especially for very large values for i, the exponent becomes very large, and rounding errors will occur. The value for ln(10) is only till 18-20 decimals. If you multiply that with a large value, say 200, the rounding occurs at the 15-17 decimal places. If you then take the exponent of that, you decrease the number of valid decimals in a major way. Then you divide an integer with that number, and the rounding errors still exist. That's why you don't get nice integers using the exp(a*ln(b)) method.
• : : : : I've just made a program which:
: : : : - reads n > 0 (let's say it 61589)
: : : : - assigns each numeral of n to an array (m)
: : : :
: : : : that means
: : : : m[1]= 9 = n mod 10
: : : : m[2]= 8 = ( (n mod 10^2) - m[1] ) /10
: : : : m[3]= 5 = ( (n mod 10^3) - m[2] ) /10^2
: : : : m[4]= 1 = ( (n mod 10^4) - m[3] ) /10^3
: : : : m[5]= 6 = ( (n mod 10^5) - m[4] ) /10^4
: : : :
: : : : as you can see, the rule is apparent:
: : : :
: : : : m[i]= ( (n mod 10^i) - m[i-1] ) / 10^(i-1)
: : : :
: : : : (with m[0]=0)
: : : :
: : : : And in Pascal, we have:
: : : : 10^i = exp(i*ln(10))
: : : :
: : : : then the formula becomes:
: : : :
: : : : m[i]= ( ( n mod trunc(exp(i*ln(10))) ) - m[i-1] ) / exp((i-1)*ln(10))
: : : :
: : : : The problem is, when execute that code, some of the m[i] are not round, I don't know if there's an error in my code, and I'm stuck with it
: : : :
: : : : Here's the code, run it, and you'll see
: : : :
: : : : [code]
: : : : program test;
: : : : uses crt;
: : : :
: : : : var l,i:integer;
: : : : m:array[0..255] of real;
: : : : n:longint;
: : : : st:string;
: : : :
: : : : begin
: : : : clrscr;
: : : : write('n:= ');readln(n);
: : : : str(n,st); {convert n to string}
: : : : l:=length(st); {and get its length}
: : : : m[0]:=0;
: : : : for i:=1 to l do
: : : : begin
: : : : m[i]:=((n mod (trunc(exp(i*ln(10)))))-m[i-1])/(exp((i-1)*ln(10))); {?????}
: : : : writeln(m[i]);
: : : : end;
: : : : writeln
: : : : writeln('Length of n = ',l);
: : : : writeln;writeln('Enter to end');
: : : : end.
: : : : [/code]
: : : :
: : : : can anybody find the reason?
: : : :
: : : exp((i-1)*ln(10) = a double. Hence the whole division becomes a double. I myself would use a much simpler code:
: : : [code]
: : : for i := 1 to l do
: : : m[i] := byte(st[l-i+1])-byte('0');
: : : [/code]
: : : This code converts each character in the string into the ASCII code, and then the ASCII of the 0-character is removed from it to make the values into 0 to 9.
: : :
: :
: : Yes, your code is indeed simplier and wiser, but I want to know why the values are not round?
: : you said the division is a double, ok, but does this affect the result?
: :
: :
: Yes, because when you calculate with doubles the computer will make rounding errors. For example:
: exp((i-1)*ln(10)) is about 10^(i-1), but especially for very large values for i, the exponent becomes very large, and rounding errors will occur. The value for ln(10) is only till 18-20 decimals. If you multiply that with a large value, say 200, the rounding occurs at the 15-17 decimal places. If you then take the exponent of that, you decrease the number of valid decimals in a major way. Then you divide an integer with that number, and the rounding errors still exist. That's why you don't get nice integers using the exp(a*ln(b)) method.
:

all right, now I understand, thank you