A little bug, I don't know why - Programmers Heaven

#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

#### Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

# A little bug, I don't know why

Posts: 29Member
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');
readln;
end.
[/code]

can anybody find the reason?

## Comments

• Posts: 6,349Member
: 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');
: readln;
: 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.
• Posts: 29Member
: : 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');
: : readln;
: : 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?

• Posts: 6,349Member
: : : 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');
: : : readln;
: : : 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.
• Posts: 29Member
: : : : 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');
: : : : readln;
: : : : 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
Sign In or Register to comment.