2010-05-14 3 views
0

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

Например,
1.

num1 = 0.94618976 
num2 = 0.94620239 

Если округлить эти цифры ДО 4 десятичного то мы получаем 0.9462 такое же количество, но я не хочу, чтобы округлить эти цифры.

2.

num1 = 0.94620239 
num2 = 0.94639125 

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

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

+0

Возможный дубликат [Круглый двойной и x значащих цифр после десятичной точки] (http://stackoverflow.com/questions/374316/round-a-double-to-x-significant-figures-after-decimal-point) –

+0

@Eli Нет, этот вопрос касается округления, мой вопрос заключается в сравнении двух двойных чисел без округления. – Himadri

+0

Какой язык программирования? Я сомневаюсь, что на это можно ответить правильно без этой информации. – Oded

ответ

2

Используйте что-то вроде SameValue из модуля Math:

if SameValue(num1, num2, 0.000099999999999) and not SameValue(num1, num2) then 
    num2 := num1; // only when different and by less then 0.0001 
+0

Afaik, который не удовлетворяет аргументу округления? –

+0

Хороший ответ, но он вернет true, если оба числа точно такие же. Я хочу true, только если они отличаются от 4-го десятичного. – Himadri

+0

@ Химадри. Отредактировано, чтобы избежать случая, когда они считаются одинаковыми. –

2

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

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

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

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

+0

Это не сработает для OP. В этом случае их следует считать одинаковыми, а с усечением они не могут. –

+0

@ François - Um. Какой из вариантов не будет работать для ОП и почему? – Oded

+0

Я не хочу усекать, но идея преобразования в строку хороша. Я даже могу преобразовать их в int путем умножения 10000. – Himadri

0

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

if (Math.Abs(Math.Round(number1, 4) - Math.Round(number2, 4)) < 0.00001) 
{ 
    number2 = number1; 
} 
+0

Участник не хочет округлять –

+0

В этом случае он также будет соответствовать, если оба значения одинаковы до 4 десятичных знаков. Я не хочу округлять. – Himadri

4

(не предполагающая никаких отрицательных чисел, и предполагая, Дельфы согласно тэгом) использовать TRUNC ().

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

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

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

+0

Вы пишете только я пишу в комментарии ответа Одеда. – Himadri

+0

Я работаю, потребовалось некоторое время, чтобы написать его. Это было параллельно. Это стандартное решение кстати. –

0

Посмотрите на устройство MATH Delph. Вы найдете подпрограммы «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

@Brian Мой вопрос о том, если условие для сравнения двух чисел не для округления – Himadri

+0

@ Химадри: Извините, я не правильно прочитал ваш вопрос. –

0

Только мысль, но как об этом:

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) 

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

+0

Ну, он должен возвращать false в случае CheckEqualUpTo4Digits (0.94618976, 0.94620239); так как он имеет 4-й разрядный. – Himadri