Максимальное число
Вопрос не про максимальное число, а про точность.
В твоём случае ты ответил на свой вопрос. 15 знаков.
В твоём случае ты ответил на свой вопрос. 15 знаков.
Читай как строку и/или использую библиотеки, которые позволяют работать с числами с произвольной точностью.
а это как ещё? какие есть библиотеки для этого?
всякие
а на чём пишешь-то?
а на чём пишешь-то?
С++ (visual)
У long double - 21 знак верный
Смысл в том, что вещественные числа расположены дискретно (ибо компьютеры конечны).
с разной плотностью - около нуля погуще, около единицы - пореже, около тысячи - ещё больше расстояния между соседними числами.
мышинным эпсилон называется расстояние между соседними числами около единицы.
для double это примерно 1e-16, для long double 1e-21, для float 1e-6
чтобы выяснить расстояние между числами около некоторого числа X, надо эпсилон умножить на это самое X.
т.е. около миллиона для float расстояние равно X*float_eps=1e6*1e-6=1. (примерно)
т.е. с точки зрения машины 1'000'000.0 и 1'000'000.5 неразличимы (для типа float)
расстояние между числами около нуля - 1e-308 (double)
И машина вполне себе нормально считает числа порядка 1e200 - складывает, умножает. тут только надо себе отчёт отдавать в том, сколько знаков мы имеем.
с разной плотностью - около нуля погуще, около единицы - пореже, около тысячи - ещё больше расстояния между соседними числами.
мышинным эпсилон называется расстояние между соседними числами около единицы.
для double это примерно 1e-16, для long double 1e-21, для float 1e-6
чтобы выяснить расстояние между числами около некоторого числа X, надо эпсилон умножить на это самое X.
т.е. около миллиона для float расстояние равно X*float_eps=1e6*1e-6=1. (примерно)
т.е. с точки зрения машины 1'000'000.0 и 1'000'000.5 неразличимы (для типа float)
расстояние между числами около нуля - 1e-308 (double)
И машина вполне себе нормально считает числа порядка 1e200 - складывает, умножает. тут только надо себе отчёт отдавать в том, сколько знаков мы имеем.
Используй GMP если тебе нужна большая точность.
Это просто Макаров-Землянский прикалывается, просит чтобы ему в виде %30.30f выводило, а машина по этому поводу ерунду выдает....и никак не сдать ему задачку..
Может он просто ждёт от тебя того ответа, который написал ?
Что б ты ему объяснил, что так не бывает.
Что б ты ему объяснил, что так не бывает.
на самом деле так и есть (т.е. он всегда выпендривается в хорошем смысле..перед студентами первого курса типа вы этого не знаете, а я вот знаю.. тока я пока не совсем уверена, что именно такой ответ...(сорри)
до пятница все равно разберусь (придется) =)
Даже был такой случай: я сидела в 13-08 а он у кого-то прогу принимал со словами "а ща я покажу, как нужно делать, чтобы прога зависла и не работала..гыгы"...
до пятница все равно разберусь (придется) =)
Даже был такой случай: я сидела в 13-08 а он у кого-то прогу принимал со словами "а ща я покажу, как нужно делать, чтобы прога зависла и не работала..гыгы"...
Сорри. Ошибся с полом 

тока что написала прогу (две строчки) чтобы считало машинный ноль..
eps=1.110223e-16 и для double, float, long double. почему так?
eps=1.110223e-16 и для double, float, long double. почему так?
Прогу в студию.
"Ай-яй-яй" другое говорит.
---
...Я работаю антинаучным аферистом...
"Ай-яй-яй" другое говорит.
---
...Я работаю антинаучным аферистом...
#include <stdio.h>
#include <math.h>
double eps;
void main
{
eps=1.;
while 1.+eps)>1)
{
eps/=2;
}
printf("eps=%.10le\n",eps);
}
вот оно
#include <math.h>
double eps;
void main
{
eps=1.;
while 1.+eps)>1)
{
eps/=2;
}
printf("eps=%.10le\n",eps);
}
вот оно
Неправильно! надо так:
long double на MSVS 7.0 почему-то кажет тот же результат, что и дабл.
на gcc всё пучком
#include <stdio.h>
#include <math.h>
typedef float mytype;
mytype eps,one,tmp;
void main
{
eps=1.;
one=1.;
tmp=one+eps;
while (tmp>one)
{
eps/=2;
tmp=one+eps;
}
printf("eps=%g\n",eps);
}
long double на MSVS 7.0 почему-то кажет тот же результат, что и дабл.
на gcc всё пучком
Ты бы хоть пояснил, какого типа значение "1.".
Опять же, это не очень-то нуль.
Или подразумевалась именно наименьшая достижимая относительная
погрешность?
---
...Я работаю антинаучным аферистом...
Опять же, это не очень-то нуль.
Или подразумевалась именно наименьшая достижимая относительная
погрешность?
---
...Я работаю антинаучным аферистом...
Вообще-то все ораторы немного заблуждаются. Нас когда-то учили, что эта самая максимальная точность еще зависит от того, какие операции над числами выполнять.
Простой пример:
для gcc, double получаем
eps+ = 5.551115e-17, i=54
eps- = 4.940656e-324, i=1075
Простой пример:
#include <math.h>
int main
{
int i=0;
double a=0;
double eps=1, eps1;
while(a != (double)1.0) {
eps /= (double)2.0;
a += eps;
i++;
}
printf("eps+ = %le, i=%d\n", eps, i);
i=0;
a=(double)1.0;
eps = 1;
while(a != (double)0.0 && eps != (double)0.0) {
eps1 = eps;
eps /= (double)2.0;
a -= eps;
i++;
}
printf("eps- = %le, i=%d\n", eps1, i);
return 0;
}
для gcc, double получаем
eps+ = 5.551115e-17, i=54
eps- = 4.940656e-324, i=1075
Мне безразлично сколько --- я могу узнать, что говорит
"Ай-яй-яй," но ты неправ.
---
...Я работаю антинаучным аферистом...
"Ай-яй-яй," но ты неправ.
---
...Я работаю антинаучным аферистом...
но ты неправ.
В чем именно я не прав? Ты действительно считаешь, что компьютерная точность вычислений не зависит от постановки вычислений?
И чем же я не прав?
у меня gcc на три типа выдаёт разные результаты - порядка 1e-8, 1e-16, 1e-22
постановка задачи была - посчитать (оценить порядок) расстояние между числами в окрестности единицы.
я считаю, приведённая программа с этой задачей справилась.
у меня gcc на три типа выдаёт разные результаты - порядка 1e-8, 1e-16, 1e-22
постановка задачи была - посчитать (оценить порядок) расстояние между числами в окрестности единицы.
я считаю, приведённая программа с этой задачей справилась.
В том, что наименьшая достижимая погрешность зависит от
способа вычислений.
---
...Я работаю антинаучным аферистом...
способа вычислений.
---
...Я работаю антинаучным аферистом...
long double на MSVS 7.0 почему-то кажет тот же результат, что и дабл.
(Я этого не делал, но думаю что можно даже догадаться почему, если поглядеть в ассемблерный листинг программы

скомпилял два файла - с даблом и лонг даблом.
fc: no differences encountered
fc: no differences encountered
я очень сомневаюсь, что машинная точность зависит от типа.....я ведь не ищу точность типа, а ищу точность машины...
...а что касается подключить библиотеку, то как я это сделаю в комп классе? и я про то..
в любом случае, всем спасибо..
...а что касается подключить библиотеку, то как я это сделаю в комп классе? и я про то..
в любом случае, всем спасибо..
Маза у MS long double 8-байтовый
В абстрактных языках программирования на абстрактных компьютерах, она, конечно же не зависит от постановки вычислений.
Но если перейти к конкретной прикладной задаче - вычисления на C на x86, то точность результата от постановки вычислений зависит. Существует достаточно классический пример (программу для иллюстрации лень писать):
Будем вычислять значение функции разложением в ряд. Возьмем достаточное количество членов ряда, чтобы наверняка превысить компьютерную точность, и посчитаем две суммы: одну начиная суммирование с больших членов ряда к меньшим, а вторую - наоборот, от меньших членов к большим. Результаты будут различаться.
Но если перейти к конкретной прикладной задаче - вычисления на C на x86, то точность результата от постановки вычислений зависит. Существует достаточно классический пример (программу для иллюстрации лень писать):
Будем вычислять значение функции разложением в ряд. Возьмем достаточное количество членов ряда, чтобы наверняка превысить компьютерную точность, и посчитаем две суммы: одну начиная суммирование с больших членов ряда к меньшим, а вторую - наоборот, от меньших членов к большим. Результаты будут различаться.
И чем же я не прав?
постановка задачи была - посчитать (оценить порядок) расстояние между числами в окрестности единицы.
я считаю, приведённая программа с этой задачей справилась.
приведенный мной пример тоже считает точность в окрестностях единицы. Только первая точность получается в окрестностях единицы, если к ней приближаться со стороны 0, а вторая - если приближаться со стороны +oo. Результаты различаются. Зависят от постановки вычислений.
Прости дядя, но ты описался... ну или лапши у тебя излишек
первый цикл действительно считает что-то в районе 1
но второй то в районе нуля...
Поэтому такая разительная разница... .940656e-324
324-16=308 точность предсказанная базилио
первый цикл действительно считает что-то в районе 1
но второй то в районе нуля...
Поэтому такая разительная разница... .940656e-324
324-16=308 точность предсказанная базилио
определение машинного нуля: минимально возможное eps, для котор верно eps+1>1
вот нафлудили-то, я ещё больше запуталась....
вот нафлудили-то, я ещё больше запуталась....
Ладно тебе придираться к мелочам. Просто что под руками было, то и заслал copy-paste'ом.
Держи правильный подсчет при приближении от 0 и приближении от 2. Результаты получишь разные, конечно не 1e-324 как у 0, но один порядок разницы все равно есть:
eps+ = 5.551115e-017, i=54
eps- = 2.220446e-016, i=53
Держи правильный подсчет при приближении от 0 и приближении от 2. Результаты получишь разные, конечно не 1e-324 как у 0, но один порядок разницы все равно есть:
#include <math.h>
int main
{
int i=0;
double a=0;
double eps=1, eps1;
while(a != (double)1.0) {
eps /= (double)2.0;
a += eps;
i++;
}
printf("eps+ = %le, i=%d\n", eps, i);
i=0;
a=(double)2.0;
eps = 1;
while(a != (double)1.0 && eps != (double)0.0) {
eps1 = eps;
eps /= (double)2.0;
a -= eps;
i++;
}
printf("eps- = %le, i=%d\n", eps1, i);
return 0;
}
eps+ = 5.551115e-017, i=54
eps- = 2.220446e-016, i=53
определение машинного нуля: минимально возможное eps, для котор верно eps+1>1
Корявое определение. Чем хуже минимальное eps', для которого верно 1-eps' < 1?
Для справки, eps != eps'.
eps+1>1
С чего бы это вдруг...
Console.WriteLine(float.Epsilon.ToString + " " + double.Epsilon.ToString;
1.401298E-45 4.94065645841247E-324
C# вполне удовлетворяет IEEE 754, так что епсилоны ДОЛЖНЫ быть такими.
2Лео: что за херня, причем тут точность вычислений?
Флоат состоит из одного байта экспоненты, одного бита знака и 23 битов мантиссы. Чтобы из этого всего получить число, например, в десятичной системе счисления следует:
1) дописать к мантиссе слева двоичную единичку и перевести ее в десятичную систему счисления.
2) умножить мантиссу на 2^экспонента, воспринимая экспоненту как число от -128 до 127. Хотя тут уже хз, мб из нее еще что-нить вычесть надо, но это совершенно не важно.
3) в зависимости от бита знака умножить результат на +1 или -1.
Все!
Соответственно, можно поставить вопрос: какое ближайшее к нулю положительное число можно записать флоатом. Ответ выше. Кстати, положительные и отрицательные числа симметричны.
Еще можно поставить вопрос, какое ближайшее к 1 положительное число большее 1 можно записать флоатом. Вроде как должно получится 1 + 2^(-23) или 1 + 2^(-24).
С чего бы это вдруг...
Console.WriteLine(float.Epsilon.ToString + " " + double.Epsilon.ToString;
1.401298E-45 4.94065645841247E-324
C# вполне удовлетворяет IEEE 754, так что епсилоны ДОЛЖНЫ быть такими.
2Лео: что за херня, причем тут точность вычислений?
Флоат состоит из одного байта экспоненты, одного бита знака и 23 битов мантиссы. Чтобы из этого всего получить число, например, в десятичной системе счисления следует:
1) дописать к мантиссе слева двоичную единичку и перевести ее в десятичную систему счисления.
2) умножить мантиссу на 2^экспонента, воспринимая экспоненту как число от -128 до 127. Хотя тут уже хз, мб из нее еще что-нить вычесть надо, но это совершенно не важно.
3) в зависимости от бита знака умножить результат на +1 или -1.
Все!
Соответственно, можно поставить вопрос: какое ближайшее к нулю положительное число можно записать флоатом. Ответ выше. Кстати, положительные и отрицательные числа симметричны.
Еще можно поставить вопрос, какое ближайшее к 1 положительное число большее 1 можно записать флоатом. Вроде как должно получится 1 + 2^(-23) или 1 + 2^(-24).
Забавно. В VS2003 тоже никаких различий.
Охбля. Почитал ваши проги. Большего долбоебства в жизни не видел.
{
int i = Magick_Constant;
float f;
f = *float*)&i);
printf("%f", f);
}
А дальше в течение пятнадцати минут при помощи Магической Константы полностью определяется формат флоата. А заодно и все возможные эпсилоны, которые только могут придти в голову.
Кстати, надо еще учитывать, что некоторые комбинации зарезервированны под nan и +-inf.
{
int i = Magick_Constant;
float f;
f = *float*)&i);
printf("%f", f);
}
А дальше в течение пятнадцати минут при помощи Магической Константы полностью определяется формат флоата. А заодно и все возможные эпсилоны, которые только могут придти в голову.
Кстати, надо еще учитывать, что некоторые комбинации зарезервированны под nan и +-inf.
Еще можно поставить вопрос, какое ближайшее к 1 положительное число большее 1 можно записать флоатом. Вроде как должно получится 1 + 2^(-23) или 1 + 2^(-24).
Ответ на вопрос какое ближайшее к X положительное число можно записать флоатом не равен тому, что ты написал. Ответ на этот вопрос очень сильно зависит от X. Если ты аккуратно запишешь действия, которые нужны для сложения двух чисел с разными мантиссами, то с удивлением обнаружишь, что число 1+2^(-23) неотличимо от числа 1.
А число 100 неотличимо от числа 100 + 1e-14. А число 10000 неотличимо от 10000 + 1-12. И так далее.
Просто ты, как и многие, путаешь минимальное число, отличимое от 0 (безусловно, равное float.Epsilon в терминах C# и минимальное число, отличимое от X.
Это тебе в подспорье, для проверки таких гипотез на языке C#, соответствующем стандарту IEEE 754.
using System;
namespace Epsilon
{
class Eps
{
[STAThread]
static void Main(string[] args)
{
float eps1, eps;
float x = 1.0F;
eps1 = eps = 1.0F;
while(eps != (float)0.0 && x+eps>x)
{
eps1 = eps;
eps /= (float)2.0;
}
Console.WriteLine("eps+ = " + eps1);
eps1 = eps = 1.0F;
while(eps != (float)0.0 && x-eps<x)
{
eps1 = eps;
eps /= (float)2.0;
}
Console.WriteLine("eps- = " + eps1);
}
}
}
Ты не понимаешь сути проблемы. Внимательно прочитай , специально для тебя сейчас выделю жирным важный момент.
ну и не на порядок, а всего в 4 раза, и то сами то eps различаются всего в 2 раза, но во втором случае ты выводишь
eps с предыдущего шага, если бы ты это делал в первом случа то выводимые числа сравнялись, а так
этот эффект удобнее наблюдать на другой программе
#include <math.h>
int main{
int i=0;
double a=0;
double eps=1, eps1;
eps=1;
for(i=1;i<100;i++){
eps /= (double)2.0;
printf(" %d= %le, %d!",i,epsdouble)1.0) != double)1.0 - eps) + (eps/(double)2.0;
printf(" %d\n"double)1.0) != double)1.0 + eps) - (eps/(double)2.0;
}
return 0;
}
в первом принтфе 1 не получается дольше.
ЗЫ Кстати я не очень понимаю почему работает твоя программа, если делать в уме, то единица там не должна получиться по крайней мере
во втором случае. Возможно я просто не понимаю округлений при действиях.
eps с предыдущего шага, если бы ты это делал в первом случа то выводимые числа сравнялись, а так
этот эффект удобнее наблюдать на другой программе
#include <math.h>
int main{
int i=0;
double a=0;
double eps=1, eps1;
eps=1;
for(i=1;i<100;i++){
eps /= (double)2.0;
printf(" %d= %le, %d!",i,epsdouble)1.0) != double)1.0 - eps) + (eps/(double)2.0;
printf(" %d\n"double)1.0) != double)1.0 + eps) - (eps/(double)2.0;
}
return 0;
}
в первом принтфе 1 не получается дольше.
ЗЫ Кстати я не очень понимаю почему работает твоя программа, если делать в уме, то единица там не должна получиться по крайней мере
во втором случае. Возможно я просто не понимаю округлений при действиях.
Проблема там не в округлениях при действиях, а в сравнении чисел с разной мантиссой. Это вносит свои ограничения. Если поискать eps в районе 0 и в районе 1e10, то его отличие от результатата для 1 может сильно впечатлить.
какое ближайшее к 1 положительное число большее 1 можно записать флоатомДружок! Где ты в вышеприведенной цытате увидел букву Х?
Просто ты, как и многие, путаешь минимальное число, отличимое от 0 (безусловно, равное float.Epsilon в терминах C# и минимальное число, отличимое от X.Просто ты, как и многие, невнимательно читаешь чужие посты. Да и вообще немного туповат.
float one = 1;
float eps = (float)Math.Pow(2, -24);
float onemore1 = one + eps;
float delta1 = onemore1 - one;
float onemore2 = one + eps*1.01f;
float delta2 = onemore2 - one;
float onemore3 = one + eps*0.99f;
float delta3 = onemore3 - one;
Console.WriteLine("{0:F10} {1:F10} {2:F10} {3:F10}", onemore1, onemore2, onemore3, eps);
Console.WriteLine("{0:F10} {1:F10} {2:F10}", delta1, delta2, delta3);
1,0000000000 1,0000000000 1,0000000000 0,0000000596Такой изврат понадобился от того, что врайтлайн отрубает последний десятичный знак.
0,0000000000 0,0000001192 0,0000000000
Итак, как мы видим моя гипотеза о 1 + 10(-24) (или -23, хз как там с округлением) гениально подтвердилась.
2Шурик: видишь ли, на иеее документация платная, а искать ее в другом месте было влом. Особенно что там дохуя говна, наверное, а тут такой тривиальный вопрос.
ммда и все равно я не понимаю, почему
1.111...11e1==1.0e0 в двоичной записи
либо добавление 1/2^n в какой-то
момент округляет первое число до 1
либо сравнение ведется с точностью до
какой-то констатнты заведомо больше
машинного eps, тогда твои и базилио расчеты неверны -
надо добавлять предполагаемый eps много раз
(а именно 2^ (разница между степенью eps и степенью округления сравнения чтобы
убедиться что ничего не добавляется
1.111...11e1==1.0e0 в двоичной записи
либо добавление 1/2^n в какой-то
момент округляет первое число до 1
либо сравнение ведется с точностью до
какой-то констатнты заведомо больше
машинного eps, тогда твои и базилио расчеты неверны -
надо добавлять предполагаемый eps много раз
(а именно 2^ (разница между степенью eps и степенью округления сравнения чтобы
убедиться что ничего не добавляется
Оставить комментарий
Marina11
Такой вопрос возник..есть ну так сказать " машинный ноль" только в обратную сторону, т.е. максимальное число, котор машина может считать (ответ : для double 1.7e-308...1.7e+308 не рассматривается)? Просто возникла такая проблема, что машина читает из файла число с 30ю знаками, но из них только первые 15 верны, а дальше какие-то др числа ставит.. типа не получается у неё такое большое число прочитать...