Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Longintegers and ord(letters) 1

Status
Not open for further replies.

gwar2k1

Programmer
Apr 17, 2003
387
GB
Hey... im working on that same program again, you know, the one with teh numbers! lol
Any way Ive hit another problem...

value is longint
input is string

a is 2187 h is 1. each letter is 3 times smaller than the previous one.

value := ((ord(input) - 64) * a);

That works perfectly when input is A (oh im using upcase aswell) to N (1 - 14) but when a letter higher than N (O-Z) is used, it doesnt do the maths right. It goes into a negative number.

Im using longint so I dont understand why its doing this. Can anyone explain why please? Thanx

~*Gwar3k1*~
"To the pressure, everything's just like: an illusion. I'll be losing you before long..."
 
Hey Gwar!

You do not mention the type of var a. I'm guessing that you set a to be an Integer. Try LongInt instead. Oh, by the way, the input var should be type char, not string -at least in BP7.

Regards


Jakob

Here's the test program I wrote:
[tt]
Program ChLoop;

Var
Value : LongInt;
Input : Char;
A : LongInt;
ChLoop : Integer;
Begin
WriteLn('Char Loop Test');
A := $2187;
For ChLoop := 65 to 90 do
Begin
Input := Chr(ChLoop);
Value := ((ord(Input)-64)*a);
Write(Input, '= ', Value:6, ' ');
End;
WriteLn;
End.
[/tt]
 
a,b,c,d,e,f,g,h are constants with the values 2187, 729, 243, 81, 27, 9, 3, 1

Input is a string from which Im selecting individual characters in a FOR i... loop



~*Gwar3k1*~
"To the pressure, everything's just like: an illusion. I'll be losing you before long..."
 
Hey Gwar,

Then I don't think I follow you. If you colud post part of the code, then I'll have another look @ it.

Regards


Jakob
 
Separate constants belonging together are an ugly thing, use arrays:
Code:
CONST multiples_of_3:array[1..8] of word = (2187, 729, 243, 81, 27, 9, 3, 1);

Furthermore, the ord function works on ordinal types and string isn't an ordinal.
If you wish to convert a string representing a number to a number, use the str procedure:
Code:
var s : string
    i : <number>; { may be byte, shortint, integer, word, longint, real, single, double, extended or comp }
str(s,i);

Regards,
Bert Vingerhoets
vingerhoetsbert@hotmail.com
Don't worry what people think about you. They're too busy wondering what you think about them.
 
I think another thing that might be going on, is that even if you are calculating a value that is to be put in a variable of type longint, the calculation will not necessarily be carried out in longint sized variables if all the things that are being handled are smaller than that. If you do a lot of maths with bytes or short integers, the compiler may do all the maths there in a byte, and then turn the final byte into a longint rather than putting the original bytes into longint size calculations.

Does that make any sense? BertV might correct me on this, I suspect he knows more than I do about pascal's habits in dealing with calculations involving mixed variable types.
 
Im using someones tip from the Aaaargh! Strings Chars and Integers thread where you index the string. Im happy with that way and it works

I was thinking that yeah, maybe like lionelhill siad there's a type difference.

PROCEDURE total_password(input:string);

CONST
a = 2187;
b = 729;
c = 243;
d = 81;
e = 27;
f = 9;
g = 3;
h = 1;

VAR
s : string[8];
i : integer;
value : longint;
v : string;

BEGIN
value := 0;
FOR i := 1 TO length(input) DO
input := upcase(input);
FOR i := 1 TO length(input) DO
BEGIN
CASE i OF
1 : value := value + ((ord(input) - 64) * a);
2 : value := value + ((ord(input) - 64) * b);
3 : value := value + ((ord(input) - 64) * c);
4 : value := value + ((ord(input) - 64) * d);
5 : value := value + ((ord(input) - 64) * e);
6 : value := value + ((ord(input) - 64) * f);
7 : value := value + ((ord(input) - 64) * g);
8 : value := value + ((ord(input) - 64) * h);
END;
gotoxy(1,i);
write(value); {using this to test it in top left corner}
END;
str((ord(input[1])-64),v);
writeln(36,33,v);
END;

Thats the procedure that calculates the value

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
Either you didn't turn off TGML :) or you don't seem to have grasped the concept of adressing strings as arrays of char yet: upcase(input) makes no sense, moreover, it generates a compile error: &quot;character expression expected&quot;. What you should use is
Code:
input[i]:=upcase(input[i])
.
When using the letter &quot;i&quot; as index in an array, you turn on italics; the best way to solve this is to put your code between [ code ] and [ /code ] labels (without the spaces).

As for calculation overflows: if you write an arithmetic expression of which the resulting value can exceed 16 bit, but doesnt't include any 32 bit variable (longint), you lose the overflow and the resulting value will not be the desired one. If no longints are used, the 16 bit register AX is used and overflows aren't saved. If your expression starts with a 32 bit value, AX:DX is automatically used for the rest of the calculation. If you have overflow troubles, you can always cast the first subexpression to a longint: <longint>:=longint(<first value>) <rest of expression>;
Example:
Code:
w1:=1000;
w2:=500;
l:=w1*w2;
=> l = 41248
Code:
l:=longint(w1)*w2;
=> l = 500000



Regards,
Bert Vingerhoets
vingerhoetsbert@hotmail.com
Don't worry what people think about you. They're too busy wondering what you think about them.
 
didnt turn off the TGML ^^; Ill try it out when I get home thanks.

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
I wrote this small program to test it out:

PROGRAM test;

USES crt;

CONST
a = 2187;

VAR
s1 : integer;
value : longint;

BEGIN
clrscr;
s1 := ord('O') - 64;
s1 := longint(s1);
value := s1 * a;
writeln(value);
readln;
END.

But it has the same result. A - N work fine but O+ dont =(

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
Oh wait... sorry didnt follow your advice 100% yeah I got it to work. You cant set it as a long int then use it you have to set it as long int as you use it right?

Thanx again

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
Consider the line
Code:
s1:=longint(s1);
- s1 is a variable of type word, occupying AX
- converted to longint, it occupies AX:DX
- stored in s1 back again, the DX part in AX:DX is discarded
- net effect: nothing changed

Either the cast should be applied on the first value of the expression in that same expression or you should convert it using an extra variable.
Example (both lines are equivalent):
Code:
l:=s1; value:=l*a; { with l : longint }
value:=longint(s1)*a;

Regards,
Bert Vingerhoets
vingerhoetsbert@hotmail.com
Don't worry what people think about you. They're too busy wondering what you think about them.
 
Thanks for the theory. Im a dumbass at the best of times! lol. Thanks again, its workin like a dream at the moment =D

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top