2016-08-23 4 views
0

вопрос, который я видел и не совсем понял.умножение переменных удвоений

сначала создавать произвольные значения:

int x = random(); 
int y = random(); 
int z = random(); 

(ИНТ 32 бита) затем продолжить:

double dx = (double) x; 
double dy = (double) y; 
double dz = (double) z; 

(двойная 64 бит)

вопрос должен был сказать если следующие операторы: всегда true (возвращает 1) или нет.

a. dx+dy+dz==dz+dy+dx 

b. dx*dy*dz==dz*dy*dx 

ответ на вопрос (а) был «да, в диапазоне точного представления, дважды в» (так, он или она не всегда правда? И если это не всегда правда, Я хотел бы привести пример из 3 значений для dx, dy, dz, который возвращает 0)

ответ на (b) был «нет», например, dx = Tmax, dy = Tmax-1, dz = Tmax-2 » я попытался и оказался таким же результатом (но, скорее всего, я ошибался: - /)

Я хотел бы понять, почему эти ответы верны.

спасибо!

ответ

1

В арифметике с плавающей точкой, вы должны never проверить на равенство. Классическим примером является 0.1 + 0.2 != 0.3. (См. http://0.30000000000000004.com/ для получения дополнительной информации, в частности, чтобы узнать, скрывает ли ваш язык от вас этот язык. У него есть хорошее объяснение того, как это возникает из-за того, что 0,1 и 0,3 не могут быть точно представлены в двухместных номерах.) Значения с плавающей запятой должны быть проверены на посмотрите, достаточно ли они близки друг к другу в определенном диапазоне, обычно называемом «толерантность».

См определение IEEE 754: https://en.wikipedia.org/wiki/Double-precision_floating-point_format

Я не согласен с ответом (а), потому что это бессмысленно, чтобы указать, что может быть «точно представлена» двойником - если каждый вход двойное представление заданные случайные биты (x, y, z), то это, по определению, точное представление. Плюс, сомнительно сказать «да, но только при некоторых условиях» в качестве ответа на вопрос «это всегда правда?» Ответ в этом случае «нет».

Один контрпример для (a) приведен ниже. Я построил это, считая, что числа с плавающей запятой имеют только определенную относительную точность, поэтому добавление очень небольшого числа к очень большому может не иметь никакого значения. Сделайте это маленькое число достаточно большим, и оно будет.

  • 1e16 + 1 + 1 = 10000000000000000
  • 1 + 1 + 1e16 = 10000000000000002

А (б), то первая вещь, которую я случайно попытался было контрпример:

  • 0.1 * 0.1 * 0.7 = 0.007000000000000001
  • 0.7 * 0.1 * 0.1 = 0.006999999999999999