2012-12-04 3 views
3

Мне интересно, как преобразовать целое число в long_integer и long_integer в Positive_Count. Каждый способ, который я пробовал, дал мне и ошибку, хотя преобразование должно быть простым в этом случае.Преобразование чисел в Ada

Например, делая

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

сделает долго отрицательное значение иногда даже если оба целое были положительными.

Код функции Я бегу, шаги расколоть для отладки:

--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; 

вызывающей функции:

calcKey("abcdef",k); 
calcKey("abcdef",k); 
calcKey("abcdef",k); 
calcKey("abcdef",k); 
calcKey("fedvba",k); 
calcKey("fedvba",k); 

Выход:

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 

ответ

3

(это должно комментарий, но он слишком длинный, поэтому я отправляю его как ответ)

Первое, что я бы на самом деле проверить, что long_int является то, что вы думаете, что это, то есть делать INTEGER'SIZE и LONG_INTEGER'SIZE, это вполне может быть, что на вашей платформе они в том же размере,

Из определения Ada :

Обратите внимание, что диапазоны и размеры этих типов могут быть разными в каждой платформы (за исключением, конечно, для булевых и [[Wide_] Wide_] Character). Существует требование реализации: размер типа Integer не менее 16 бит, а для Long_Integer - не менее 32 бит (если имеется) RM 3.5.4 (21..22) (аннотированный). Поэтому, если вы используете , вам нужна полная переносимость ваших типов, не используйте типы из стандарта (за исключением случаев, когда вы должны, см. Ниже), скорее определите собственные типы. Компилятор отклонит любое объявление типа, диапазон которого не может удовлетворять .

Если они имеют одинаковый размер, вы можете переполняться при добавлении 2 действительно больших целых чисел, что дает результаты, которые вы видите.

Источник: http://en.wikibooks.org/wiki/Ada_Programming/Libraries/Standard

+0

Да. Целое и Long_Integer имеют одинаковый размер. Спасибо. – user1279914

4

Предыдущий ответ правильный на необходимость (и правильно), чтобы проверить целочисленные размеры.

В качестве альтернативы, определите свои собственные целые типы и выполните «проблему»!

Но если целочисленное добавление переполнено и возвращает отрицательные числа, вы не используете компилятор Ada!

К сожалению, Gnat не является компилятором Ada по умолчанию.

С помощью Gnat вам необходимо установить флаги компилятора для включения таких проверок, как переполнение, которые по умолчанию должны быть включены. Тогда такое переполнение вызовет исключение Constraint_Error с сообщением, указывающим прямо на строку кода, которая не удалась, - делает тестирование намного проще, чем реинжиниринг, что пошло не так!

gnatmake -gnataeEfoUv -fstack-check my_main.adb 

довольно обширный набор, который, вероятно, включает в себя некоторые проверки стиля вы не хотите: проверить комар документации для получения более подробной информации.

Другие предложения по выбору предпочтительных флагов.

Если вы используете другой компилятор, мне было бы интересно узнать, что это такое.

Кстати, вы не предоставили функцию StringToInt, чтобы никто не мог проверить ваш пример, но я хотел бы указать, что значения, которые он генерирует, в отличие от значений, которые я ожидал бы от строк, которые вы предоставляете ... это случайный хэш-генератор?

+0

Это плохой случайный хеш-генератор, который мне нужно использовать для задания. Я думаю, что нечетные значения остаются за данными мусора в целых числах, потому что они имеют разные размеры, чем строки. В моем задании указано, что строка и целое число имеют тот же размер, который, как я теперь знаю, неверен. Я научил себя Аде для этого класса, поэтому я все еще многому учусь. Я использую Gnat и GPS. – user1279914

Смежные вопросы