Форум: "Потрепаться";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];
ВнизПочему так? Найти похожие ветки
← →
SergP © (2004-07-08 23:54) [0]Почему эти два куска кода работают по разному?
function proverka1(a:byte):boolean;
begin
a:=a-30;
result:=a<5;
end;
function proverka2(a:byte):boolean;
begin
result:=(a-30)<5;
end;
← →
Palladin © (2004-07-08 23:58) [1]Это в каком смысле они по разному работают?
← →
SergP © (2004-07-08 23:59) [2]Код который генерит компилятор я не смотрел. Лень...
Но интерестно как он считает:
result:=(a-30)<5 ?
Преобразовывает это в
result:=a<35 или при вычислении a-30 использует результат не типа byte ?
← →
DeadMeat © (2004-07-09 00:00) [3]
> result:=a<35 или при вычислении a-30 использует результат
> не типа byte ?
Скорее всего...
---
...Death Is Only The Begining...
← →
SergP © (2004-07-09 00:00) [4]
> [1] Palladin © (08.07.04 23:58)
> Это в каком смысле они по разному работают?
при некоторых одинаковых значениях аргумента обе функции выдают разные результаты...
← →
YurikGL © (2004-07-09 00:02) [5]
> при некоторых одинаковых значениях аргумента обе функции
> выдают разные результаты...
Видимо, при а<30 ?
← →
Palladin © (2004-07-09 00:06) [6]я не поленился...
В первом варианте от значения находящегося в стеке отнимается 30 и потом это значение сравнивается... используется сравнение с al
Во втором варианте все приводится к 32 и идет обработка eax...
почему? вопрос к borland...
← →
SergP © (2004-07-09 00:09) [7]
> Видимо, при а<30 ?
Ага...
← →
YurikGL © (2004-07-09 00:10) [8]
> SergP © (09.07.04 00:09) [7]
Могу попробовать объяснить по простому, в первом случае результат приводится к byte, во втором, - к longint или чему-то подобному.
← →
Palladin © (2004-07-09 00:11) [9]А конкретный пример разного результата можно привести?
← →
DeadMeat © (2004-07-09 00:12) [10]Если а будет меньше 30... т.е. 29, 28, 27, 26... Кажись так...
---
...Death Is Only The Begining...
← →
Anatoly Podgoretsky © (2004-07-09 00:14) [11]Так нельзя использовать, байт это беззнаковое, а при -30 может произойти переполнение.
← →
SergP © (2004-07-09 00:17) [12]
> [9] Palladin © (09.07.04 00:11)
> А конкретный пример разного результата можно привести?
при a>=35
proverka1=false
proverka2=false
при 30<=a<35
proverka1=true
proverka2=true
При a<30 имеем разные результаты:
proverka1=false
proverka2=true
← →
jack128 © (2004-07-09 00:17) [13]
> Так нельзя использовать, байт это беззнаковое, а при -30
> может произойти переполнение
оно и при +30 может произойти ;-)
← →
Palladin © (2004-07-09 00:23) [14]это очень поучительно, когда работа в стеке идет с одним байтом и когда проводится реальное сравнение... работа с параметр в первом случае как я уже сказал ведется как с байтом (al), соответсвенно 10-30=235 что естественно больше чем 30... во втором случае все справедливо переводится в знаковое integer и сравнение происходит корректно...
← →
jack128 © (2004-07-09 00:30) [15]
> это очень поучительно,
угу. C {$R+} и {$Q+} - навсегда -)
← →
Piter © (2004-07-09 00:46) [16]ну тут уже ответили, но вставлю свои пять копеек...
Это потому что вычисления проводятся как integer, а потом идет приведение типов.a:=a-30;
result:=a<5;
Допустим, параметр "a=20".
В этом случае "a-30" будет "-10".
Потом идет приведение типов, "-10" приводится к типу Byte (к левой части). В этом случае получается, что "a=246". Ибо "-10", а точнее $F6 в понимании Byte это 246.
А 246 никак не меньше пяти. Значит, будет False.
Правда, при приведении "-10" к Byte будет сгенерировано исключение ERangeError, если включить галочку "Project->Options...->Compiler->Range Checking"
----------------------------------------------------------------------------------------------------function proverka2(a:byte):boolean;
begin
result:=(a-30)<5;
end;
в этом случае вычисления проводятся тоже как integer. Если "a=20", то "a-30" получается "-10". И далее не идет никакого приведения к Byte, поэтому "-10" сравнивается с "5". Конечно, 5 больше. Поэтому True.
Вот и все различия.
Только заметь, что при включенном "Range Checking" первый вариант будет выдывать исключение, а второй нет. То есть, первый вариант работает "неправильно".
Поэтому отлаживать проект надо при включенных "Range Checking" и "Overflow Checking". А в конечном билде их отключать.
Можно еще вычитать не 30, а допустим 2147483678:function proverka1(a:byte):boolean;
begin
a:=a-2147483678;
result:=a<5;
end;
function proverka2(a:byte):boolean;
begin
result:=(a-2147483678)<5;
end;
Тогда если даже "a=20" то обе функции будут все равно выдавать False (если отключить проверки на Range и Overflow).
Ибо тогда во втором случае уже будет переполнен integer.
И в понятии integer "20 - 2147483678" будет равно "2147483638" как это не парадоксально :)
А вообще http://www.baseprogram.narod.ru
← →
Anatoly Podgoretsky © (2004-07-09 01:26) [17]jack128 © (09.07.04 00:17) [13]
Да но у него отключены все проверки и при варианте 1 результат обрезается по модулю 256, а во втором случае нет.
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.036 c