2015-02-26 4 views
1

Я собираюсь кипятить эту проблему вплоть до простейшей формы:Как использовать FMOD и избежать проблем с точностью

Переберет из [0 .. 5,0] с шагом 0,05 и распечатать «X ' для каждого умножителя 0,25.

for(double d=0.0; d<=5.0; d+=0.05) { 
    if(fmod(d,0.25) is equal 0) 
    print 'X'; 
} 

Это, конечно, не работает, так как d будет [0, +0,05000000001, 0,100000000002 ...] вызывает FMOD() потерпеть неудачу. Экстремальный пример: d=1.999999999998 и fmod(d,0.25) = 1.

Как справиться с этим? Here is редактируемый онлайн-пример.

+0

Если размер шага ('0.05 здесь) может быть представлен как' 2 ** x' (** == поднят до), вы вряд ли получите '==' для float/double variables/расчеты. – anishsane

ответ

6

Я бы решить эту проблему, просто не использовать переменные с плавающей точкой таким образом:

for (int i = 0; i <= 500; i += 5) { 
    double d = i/100.0; // in case you need to use it. 
    if ((i % 25) == 0) 
    print 'X'; 
} 

Они, как правило, достаточно проблематично, что стоит немного больше усилий, избежать их.

2

В случаях, когда у вас всегда есть одна и та же фиксированная десятичная дробь, просто умножьте свой счетчик циклов (в этом случае на 20). Если вы хотите получить доступ к нему как двойнику, разделите его на 20. Фактически вы используете скрытый показатель, чтобы сохранить двойное целое.

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

for(int i=0; i<=100; i+=1) { 
    if(i % 5 == 0) 
    print 'X'; 
    double d = (double)i/20.0; 
    // use d 
}