Округление и запись, если условие - PullRequest
0 голосов
/ 14 мая 2010

У меня есть два десятичных числа. Я хочу, чтобы эти числа были одинаковыми до 4 десятичных знаков без округления. Если числа разные, я хочу заменить 2-е число на 1-е. Что если условие мне написать?

Например,
1.

num1 = 0.94618976  
num2 = 0.94620239

Если мы округлим эти числа до 4 десятичных, то получим 0,9462 того же числа, но я не хочу округлять эти числа.

2

num1 = 0.94620239  
num2 = 0.94639125  

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

Я использую Delphi, но вы можете ответить на любом языке. Спасибо.

Ответы [ 6 ]

4 голосов
/ 14 мая 2010

(при условии отсутствия отрицательных чисел и в предположении delphi в соответствии с тегом) используйте trunc ().

trunc(num1*10000.0)=trunc(num2*10000.0)

умножение на 10000 делает его целыми числами, и тогда все просто.

Если вы вычислите 10000.0 (например, с помощью мощности (10, n)), вы даже можете сделать число цифр переменной времени выполнения.

2 голосов
/ 14 мая 2010

Используйте что-то вроде SameValue из математического блока:

if SameValue(num1, num2, 0.000099999999999) and not SameValue(num1, num2) then 
  num2 := num1; // only when different and by less then 0.0001
2 голосов
/ 14 мая 2010

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

Вы можете использовать функцию усечение (это отличается от округления), которая просто отбрасывает цифры с более высокой точностью (поэтому 0.94618976 становится 0.9461, а 0.94620239 становится 0.9462 ). Вы можете сравнить результаты усечения.

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

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

0 голосов
/ 17 мая 2010

Просто мысль, но как на счет этого:

function CheckEqualUpTo4Digits(const aValue1, aValue2: Double): Boolean;
var
  Diff: Double;
begin
  Diff := Abs(aValue1 - aValue2);
  Result := (Diff < 0.0001);
end;

С этим кодом возвращается True:

CheckEqualUpTo4Digits(0.94618976, 0.94620239);

И это возвращает False:

CheckEqualUpTo4Digits(0.94620239 , 0.94639125)

Я не слишком много тестировал, но вы могли бы попробовать - по крайней мере, он не использует округление, преобразование в другой тип (например, что может произойти с усечением) и достаточно быстрый.

0 голосов
/ 14 мая 2010

Посмотрите в блок Delph MATH. Вы найдете процедуры «RoundTo» и «SimpleRoundTo».

type
 TRoundToEXRangeExtended = -20..20;

function RoundTo(const AValue: Extended;
                 const ADigit: TRoundToEXRangeExtended): Extended;

{ This variation of the RoundTo function follows the asymmetric arithmetic
  rounding algorithm (if Frac(X) < .5 then return X else return X + 1).  This
  function defaults to rounding to the hundredth's place (cents). }

function SimpleRoundTo(const AValue: Extended; const ADigit: TRoundToRange = -2): Extended;
0 голосов
/ 14 мая 2010

Что-то вроде следующего кода C #:

if (Math.Abs(Math.Round(number1, 4) - Math.Round(number2, 4)) < 0.00001)
{
    number2 = number1;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...