- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
static double SingleToDouble(Single v)
{
return double.Parse(v.ToString());
}
static void Scan()
{
double q = 0.0;
while (q <= 10.0)
{
Single s = (Single)q;
Double d = SingleToDouble(s);
if (d == q)
MessageBox.Show(q.ToString());
q = q + 0.1;
}
}
народ, кто-нибудь знает чем можно заменить код "return double.Parse(v.ToString());" в SingleToDouble?
"return v;" не подходит - на экран выводятся только 0, 0.5 и 4.5. А нужно чтобы все выводились 0, 0.1, 0.2 ... 0.9.
TarasB 16.12.2010 15:42 # +2
С чего бы? 0.1 не может быть точно представимо в компьютере, поэтому при конвертации туда-сюда такая фигня получается. Это нормально.
if (d == q)
замени на
if abs(d-q) < eps
Анонимус 16.12.2010 15:46 # +1
или не используйте плавающую точку
Em1ss1oN 16.12.2010 15:59 # +1
TarasB объяснил суть проблемы, так что с этим кодом тоже не заработает.
koodeer 16.12.2010 16:22 # +1
4eburashka 16.12.2010 16:36 # 0
еще немного подробнее о проблеме:
имеется double: q=1.1;
мы присваиваем: Single s=(Single)q;
а потом обратно в Double: double g=s;
получается, что g=0.10000000149011612, т.е. добавляются левые 0.00000000149011612.
Есть ли более "приличный" способ эти левые числа отбросить, кроме как double.Parse(q.ToString("0.########"))?
TarasB 16.12.2010 16:51 # 0
Просто запомни: никогда не сравнивай вещественные числа оператором "равно".
4eburashka 16.12.2010 17:04 # 0
В результате каких-то расчетов с плавающей запятой получается результат, который сохраняется в файл в 4-х байтном формате, т.е. Single. Формат файла строго регламентирован.
Потом, когда этот результат загрузится из файла (допустим другой программой) и преобразуется в double для дальнейших расчетов, то добавляются левые числа! Вот я и пытаюсь найти какое-нибудь средство, чтобы от левых чисел избавиться.
TarasB 16.12.2010 17:11 # +1
d := round(d*1000)*0.001
А если тебе нужно хранить точные значение, то терпи что есть.
4eburashka 16.12.2010 17:16 # 0
abatishchev 16.12.2010 17:21 # +1
LostPain 16.12.2010 17:37 # 0
koodeer 16.12.2010 18:14 # +5
Ничего лишнего ниоткуда не берётся! Это вещественные числа! А ну марш читать про них!
Они представлены в памяти так, как представлены. Не трогай их! И лишь при показе пользователю используй формат.
FadedInto 16.12.2010 19:16 # −5
0.10000000149011612 и 0.10000000000000000
одно и то же? Мы же точность увеличили с float до double.
FadedInto 16.12.2010 20:54 # −5
TarasB 17.12.2010 11:22 # 0
FadedInto 17.12.2010 12:34 # 0
4eburashka 16.12.2010 19:18 # −3
double v1 = 1.1;
double v2 = (Single)v1;
v1 *= 10000000000;
v2 *= 10000000000;
и теперь у нас
v1 = 11000000000.0
v2 = 11000000238.418579
koodeer 16.12.2010 21:20 # +4
Какой смысл в двойной точности, если на промежуточном этапе данные сохраняются в одинарной? Это говноархитектура! Своим говнокодом ты пытаешься заткнуть дыру говноархитектуры приложения.
FadedInto 16.12.2010 21:48 # +1
interested 17.12.2010 01:12 # +1
Совершенно нормально для вычислительной математики, когда точность вычислений у вас выше, чем точность результата. Для задач оптимизации максимальная точность результата -- это корень от точности вычислений (достаточно очевидно это, если с математическим анализом знакомы).
Кроме того, данные могут сохранятся где-то в определённом формате, независящем от программы, производящей вычисления.
FadedInto 17.12.2010 13:21 # 0
interested 17.12.2010 14:24 # +1
Но "говноархитектура" здесь совершенно не очевидна. (далее С++) Скажем, закладывая float в метод Рунге-Кудта второго порядка и рассчитывая во float ответ будет колебаться (то есть фазовая траектория будет "дышать"). А если внести float, рассчитать в double, и снова конвертировать во float, то ответ не изменится (всегда один и те же числа будут получаться, фазовая траектория во float стабильна, но "дышит" в double). Это как раз связано с тем, что начальные и конечные данные имеют точность ниже того, чем нужно считать.
Насколько я понимаю, в процессорах Intel даже существует дополнительное ещё более длинное число, чем double, которое используется в выражениях содержащих плавающую точку, чтобы получать, до некоторой степени, всегда один и тот же результат выражения в пределах точность double.
TarasB 17.12.2010 15:02 # 0
long double штоле?
FadedInto 17.12.2010 15:35 # 0
TarasB 17.12.2010 15:38 # +2
Просто он так назвал, как будто это новая сверхсекретная технология Интела.
bugmenot 17.12.2010 15:44 # +2
interested 17.12.2010 20:46 # 0
interested 17.12.2010 21:09 # 0
http://en.wikipedia.org/wiki/Extended_precision
inkanus-gray 17.12.2010 21:14 # 0
bugmenot 17.12.2010 21:19 # +2
а сам формат нативный, поэтому и длина неправильная получилась
inkanus-gray 17.12.2010 21:24 # 0
Говногость 17.12.2010 23:13 # +1
А с чем это связано? С выравниванием?
inkanus-gray 18.12.2010 02:05 # 0
bugmenot 17.12.2010 15:15 # +2
facepalm.for
TarasB 17.12.2010 11:23 # +3
ВЕЩЕСТВЕННЫЕ ЧИСЛА СРАВНИВАТЬ ЧЕРЕЗ ОПЕРАТОР СРАВНЕНИЯ НЕЛЬЗЯ!!!
ВЕЩЕСТВЕННЫЕ ЧИСЛА СРАВНИВАТЬ ЧЕРЕЗ ОПЕРАТОР СРАВНЕНИЯ НЕЛЬЗЯ!!!
ВЕЩЕСТВЕННЫЕ ЧИСЛА СРАВНИВАТЬ ЧЕРЕЗ ОПЕРАТОР СРАВНЕНИЯ НЕЛЬЗЯ!!!
ВЕЩЕСТВЕННЫЕ ЧИСЛА СРАВНИВАТЬ ЧЕРЕЗ ОПЕРАТОР СРАВНЕНИЯ НЕЛЬЗЯ!!!
4eburashka 17.12.2010 12:45 # −1
Какого хрена у меня погрешность возникает, когда я в более точное представление конвертирую?
TarasB 17.12.2010 12:51 # 0
То есть Single сам по себе хранит мало знаков после запятой, но для него погрешность 1Е-7 нормальна. То есть число типа 1.111111111 при выводе заменяется на 10.0
А вот те же 1Е-7 для Double уже не погрешность представления, и 1.111111111000000 выводится как есть.
4eburashka 17.12.2010 13:18 # −1
FadedInto 17.12.2010 13:23 # 0
// то есть через Math.Round(), опечатка.
TarasB 17.12.2010 13:26 # +1
TarasB 17.12.2010 13:41 # +1
Если неймётся, то используй round(x*100000)*0.00001
но лучше так не делай.
Лучше почитай книжки или википедию http://ru.wikipedia.org/wiki/Числа_с_плавающей_запятой
bugmenot 16.12.2010 17:35 # +6
PS: за обращение "народ" не стоя на броневичке хочется отдельно уебать
LostPain 16.12.2010 17:38 # −5
bugmenot 16.12.2010 17:43 # +5
просто съебись отсюда, пожалуйста.
LostPain 16.12.2010 17:49 # −9
bugmenot 16.12.2010 18:02 # +3
:-P
LostPain 16.12.2010 18:04 # 0
Ладно, извини, че то я сорвался, день видно сегодня такой.
bugmenot 16.12.2010 18:18 # +2
Lure Of Chaos 16.12.2010 18:26 # −1