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

A little bug, I don't know why

king0deuking0deu 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

  • zibadianzibadian 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.
  • king0deuking0deu 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?

  • zibadianzibadian 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.
  • king0deuking0deu 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.