Любой из заданных операторов +, -, *, /
, примененный к операндам double
, приведет к double
, а также к функциям fabs()
и pow()
.Таким образом, невозможно преобразовать double
в integer
, используя только предоставленные операторы и функции fabs()
и pow()
.
Кроме того, оператор %
предназначен только для целых чисел.Существует функция fmod()
, которая обеспечивает те же функции для чисел с плавающей запятой.
Мы можем добиться того, чтобы результат наших вычислений, используя только предоставленные операторы и функции, был представлен в памяти таким же образом, какцелые числа 0 и 1.
Например, эти функции созданы для float
, т. е. 32-битных чисел с плавающей запятой:
float largerOf(float x, float y){
return ((x + y) + fabs(x-y)) / 2.0;
}
float smallerOf(float x, float y){
return ((x + y) - fabs(x-y)) / 2.0;
}
int isEqual(float x, float y){
float tmp = smallerOf(x, y) / largerOf(x, y);
tmp /= 3.4028235E38;
tmp /= 4194303.9999999997;
return *((int*)(&tmp));
}
int lessThan(float x, float y){
float tmp = smallerOf(x, y) / x;
tmp /= 3.4028235E38;
tmp /= 4194303.9999999997;
return (*((int*)(&tmp)))-isEqual(x,y);
}
int greaterThan(float x, float y){
float tmp = smallerOf(x, y) / y;
tmp /= 3.4028235E38;
tmp /= 4194303.9999999997;
return (*((int*)(&tmp)))-isEqual(x,y);
}
В этом решении используется тот факт, что меньшее из двух значений делится набольшее из двух значений приведет к значению, меньшему или равному 1.0
.Затем результирующее значение после деления снова делится на две жестко закодированные константы в попытке получить число с плавающей запятой с установленным крайним правым битом, если и только если результат первого деления был точно 1.0
.В конце концов, мы обращаемся к памяти, содержащей число с плавающей запятой, как если бы оно содержало целочисленный результат.
Обратите внимание, что это решение плохо протестировано и, возможно, неправильно работает во многих различных отношениях.Например, значения 2.0
и 1.9999993
ведут себя хорошо, но 2.0
и 1.9999994
считаются равными, несмотря на то, что 32-разрядное число с плавающей запятой может представлять значения 1.9999993
и 1.9999994
, и они оба отличаются от 2.0
.