3

I am wondering how to convert an integer to a long_integer and a long_integer to a Positive_Count. Every way I have tried has given me and error even though the conversion should be easy in that instance.

For example, doing

long := long_integer(int1) + long_integer(int2);

will make long a negative value sometimes even though both integer were positive.

The code of the function I'm running , steps split for debugging:

--calcKey--
procedure calcKey(x: in String16; key: out External_IO.Positive_Count) is
  s1, s2 : String2;
  int1, int2 : integer;
  long1, long2 : long_integer;
begin
  s1 := x(12..13); 
  s2 := x(15..16); 
  put_line("s1: " &s1& "- s2: " &s2);
  int1 := abs StringToInt(s1);
  int2 := abs StringToInt(s2); 
  put("int1: " & Integer'image(int1) & " | int: " & Integer'Image(int2)); new_line;
  long1 := long_integer(int1); 
  long2 := long_integer(int2);
  long1 := long1 + long2; 
  put_line("long := " & long_integer'Image(long1));
  long1 := (long1 mod 256) + 1;
  key := External_IO.Positive_Count(long1); 
  put_line("Key : " & External_IO.Positive_Count'Image(key));

  new_line;
end calcKey;

calling the function:

calcKey("0123456789abcdef",k);
calcKey("0123456789abcdef",k);
calcKey("0123456789abcdef",k);
calcKey("0123456789abcdef",k);
calcKey("fedvba9876543210",k);
calcKey("fedvba9876543210",k);

The output:

s1: bc- s2: ef
int1:  2011929758 | int:  1667393125
long := -615644413
Key :  4

s1: bc- s2: ef
int1:  287586 | int:  1667393125
long :=  1667680711
Key :  200

s1: bc- s2: ef
int1:  13132642 | int:  1667393125
long :=  1680525767
Key :  200

s1: bc- s2: ef
int1:  13132642 | int:  1667393125
long :=  1680525767
Key :  200

s1: 43- s2: 10
int1:  13120308 | int:  859058225
long :=  872178533
Key :  102

s1: 43- s2: 10
int1:  6697780 | int:  859058225
long :=  865756005
Key :  102
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
user1279914
  • 185
  • 1
  • 5
  • 19

2 Answers2

4

Previous answer is correct on the need (and correct way) to check integer sizes.

Alternatively, define your own integer types and be done with the "problem"!

But if integer addition is overflowing and returning negative numbers, you are not using an Ada compiler!

It is unfortunate that Gnat is not an Ada compiler by default.

With Gnat, you need to set compiler flags to enable checks such as overflow, that really ought to be on by default. Then such an overflow will raise the Constraint_Error exception with a message pointing directly at the line of code which failed - makes testing much easier than having to reverse-engineer what went wrong!

gnatmake -gnataeEfoUv -fstack-check my_main.adb

is a fairly comprehensive set, that probably includes some style checks you don't want : check the Gnat documentation for more details.

Other suggestions for preferred flag sets welcome.

If you are using another compiler, I'd be interested to hear which it is.

Incidentally, you haven't provided the StringToInt function so nobody else can test your example, but I would point out that the values it is generating are quite unlike the values I would expect from the strings you provide... is it a random hash generator?

  • It is a bad random hash generator that I need to use for an assignment. I think the odd values are left over trash data in the integers because they are different sizes than the strings. My assignment says that the string and integer are the same size, which I now know are not true. I've taught myself Ada for this class, so I'm still learning a lot. I am using Gnat and GPS. – user1279914 Dec 04 '12 at 15:55
3

(THis should be a comment, but it's too long so I'm submitting it as an answer)

First thing I would do is actually verify that long_int is what you think it is, i.e doing INTEGER'SIZE and LONG_INTEGER'SIZE, it could very well be that on your platform they are the very same size,

From the Ada definition:

Note that the ranges and sizes of these types can be different in every platform (except of course for Boolean and [[Wide_]Wide_]Character). There is an implementation requirement that the size of type Integer is at least 16 bits, and that of Long_Integer at least 32 bits (if present) RM 3.5.4 (21..22) (Annotated). So if you want full portability of your types, do not use types from Standard (except where you must, see below), rather define you own types. A compiler will reject any type declaration whose range it cannot satisfy.

If they are the same size you could be overflowing when you add 2 really large ints, thus giving the results you see.

Source: http://en.wikibooks.org/wiki/Ada_Programming/Libraries/Standard

user439407
  • 1,666
  • 2
  • 19
  • 40