Войти

Показать полную графическую версию : помогите сделать блок-схему


Страниц : 1 [2] 3 4

mrcnn
01-12-2013, 07:24
А ведь предупреждали: не сравнивайте вещественные числа между собой. Нет же, пока САМ не обожжется - должен попробовать. // http://forum.pascalnet.ru/lofiversion/index.php/t24610.html

ВОТ ПРИМЕР КАК ОБЖИГАЮТСЯ

select * from table_name where val=1.7
Значение 1.5 остается как было, значение 1.7 меняется на 1.70000004768372. // http://www.sql.ru/forum/958491/strannyy-kosyak-s-float

ГДЕ ТА БЕСКОНЕЧНОСТЬ, КОТОРУЮ ВЫ ТУТ МНЕ ПЫТАЕТЕСЬ ДОКАЗАТЬ?

А число 1.7 в двоичной системе имеет бесконечный хвост, который сохранить полностью не представляется возможным. // http://www.sql.ru/forum/958491/strannyy-kosyak-s-float

Это, кстати, касается и случая, когда Вы сравниваете вещественные числа, не учитывая точность представления чисел. Посмотрев в отладчике, что числа, вроде как одинаковые, но сравнение срабатывает так, как будто они разные, Вы не задумались бы, что именно в сравнении содержится ошибка. // http://popoff.donetsk.ua/text/work/prg/debug.html

У вещественных чисел есть погрешность. Сравнивайте не "равно", а больше/меньше, с учетом этой погрешности. // http://linuxforum.ru/viewtopic.php?id=4076

Не сравнивайте на равенство вещественные числа. // www.intuit.ru/studies/courses/4484/1009/lecture/9252?page=2‎

Уж сколько раз твердили миру: не сравнивайте вещественные числа на равентство. // www.forum.mista.ru/topic.php?id=620586

Не сравнивайте вещественные числа оператором = (равно). Это не проблема Delphi, а свойство их представления. // http://rfpro.ru/?step=search&mode=answers&s=&user_id=0&section=5&from=110280

Iska
01-12-2013, 08:25
Это в этой программе может сравнение и работать. Но можно нарваться на ситуацию, когда она не сработает. »
Ага. Есть сдвиги. Уже «работает, но можно нарваться», вместо «никогда». Тогда приведите пример про «нарваться», когда «1/3» не будет равна «1/3».

Ваше рассуждение индуктивное. Вы пытаетесь ОДНИМ примером доказать правильность перевода вывода на весь класс предметов, и в данном случае это ошибочно. »
Это утверждение коллеги Tau_0:
ибо никогда в лоб на плавающей точке равенства не будет...
ошибочно, а вслед за ним и Ваше. Я его опровергаю «ОДНИМ» простым незатейливым примером.

Проблему неполной индукции еще никто не отменял. Это у вас сейчас работает, но в целом оно неправильно даже несмотря на то, что временно работает или работает в каких отдельных ситуациях. Ваш пример работает, потому что это временное исключение.»
Ну, ну. Повторяю уже в третьем сообщении: приведите исключение, когда «1/3» не будет равна «1/3».

Я сталкивался с ситуациями, когда 0 не был равен 0 в простых программах из-за того, что нет бесконечности. »
Эко Вас понесло. Оставим пока в покое два представления машинного нуля и т.п.

Компьютер всегда работает с приближением, поэтому разрабатываются численные методы дифференцирования, интегрирования, решения уравнений и т.д. »
Напротив. Компьютер всегда работает точно. И потому может терять представление порядка в ту или иную сторону вследствие ограниченности его (порядка) представления. И вот потому-то, что он работает точно, и разрабатываются различные методы округления для компенсации ошибок вычислений при (повторяю в третий раз) переполнении и исчезновении порядка. Но это не имеет ни малейшего отношения к тому, что два числа будут равны или не равны между собой, независимо от того, был ли потерян порядок их представления или нет, ибо порядок будет потерян равнозначно у обоих сравниваемых чисел.

Компьютеры являются дискретными устройствами, поэтому вам даже в информации о процессоре Intel i7 пишут, что видеокадаптер встроенный в процессор является дискретным. В комьютере реализуются дискретные функции, потому что нельзя реализовать непрерывные. Нельзя реальный физический мир повторить в комьютере. Есть специальный курс дискретной математики в профессиональных ВУЗах для программистов и инженеров. Реализуя компьютерный алгоритм в программе, вы всегда переводите с непрерывного класса функций на дискретный.
Бесконечности вещественных чисел в компьютере нет. Поэтому на плавающей точке в лоб равенства может не быть. В электронике на физическом уровне инженерами реализована ТОЧНОСТЬ ДО определенного ЭПСИЛОН, а не бесконечность. Я имею в виду инженеров компаний типа Intel, AMD и т.д., которые занимаются созданием чипов.
1/3 переводится к конечному представлению в компьютерах. »

А ведь предупреждали: не сравнивайте вещественные числа между собой. Нет же, пока САМ не обожжется - должен попробовать. // http://forum.pascalnet.ru/lofiversio...hp/t24610.html
ВОТ ПРИМЕР КАК ОБЖИГАЮТСЯ
select * from table_name where val=1.7
Значение 1.5 остается как было, значение 1.7 меняется на 1.70000004768372. // http://www.sql.ru/forum/958491/strannyy-kosyak-s-float
ГДЕ ТА БЕСКОНЕЧНОСТЬ, КОТОРУЮ ВЫ ТУТ МНЕ ПЫТАЕТЕСЬ ДОКАЗАТЬ?
А число 1.7 в двоичной системе имеет бесконечный хвост, который сохранить полностью не представляется возможным. // http://www.sql.ru/forum/958491/strannyy-kosyak-s-float
Это, кстати, касается и случая, когда Вы сравниваете вещественные числа, не учитывая точность представления чисел. Посмотрев в отладчике, что числа, вроде как одинаковые, но сравнение срабатывает так, как будто они разные, Вы не задумались бы, что именно в сравнении содержится ошибка. // http://popoff.donetsk.ua/text/work/prg/debug.html
У вещественных чисел есть погрешность. Сравнивайте не "равно", а больше/меньше, с учетом этой погрешности. // http://linuxforum.ru/viewtopic.php?id=4076
Не сравнивайте на равенство вещественные числа. // http://www.intuit.ru/studies/courses...?page=2‎
Уж сколько раз твердили миру: не сравнивайте вещественные числа на равентство. // www.forum.mista.ru/topic.php?id=620586
Не сравнивайте вещественные числа оператором = (равно). Это не проблема Delphi, а свойство их представления. // http://rfpro.ru/?step=search&mode=an...=5&from=110280 »
Зачем Вы мне это доказываете? Я об этом давно уже написал в этой теме, поднимите глаза долу на пост #5 (http://forum.oszone.net/post-2264212.html#post2264212). Но всё это никак не отменяет того факта, что утверждение
ибо никогда в лоб на плавающей точке равенства не будет...
ложно. Можно утверждать лишь о том, что «В результате потери или исчезновения порядка при вычислениях результаты сравнения а) могут б) в некоторых случаях оказаться некорректными», а вовсе не тот тезис, из-за которого разгорелся весь сыр-бор. И плавающая точка тут совершенно не при чём. Ровно та же логика будет, к примеру, на целых числах и целочисленных вычислениях.

mrcnn
01-12-2013, 09:27
ЭВМ оперирует структурами конечного типа. 1/3 не является в компьютере бесконечным. Выше приведен пример с числом 1.7, которое было преобразовано в 1.70000004768372 В 1/3 тоже добавляется в конец "мусор".. Вы проверяете на платформе i386 а на других платформах, например встроенных систем, мобильных устройств и т.п. ваш пример может не сработать. ВАША ПРОГРАММА БЫЛА ПРОВЕРЕНА ЛИШЬ НА ВАШЕМ КОМПЬЮТЕРЕ, но не проверялась на других платформах. Докажите сперва, что ваша программа работает вообще ? Если она на вашем компьютере работает, это не значит, что она правильная. С чего вы решили, что у вас правильный код? Может быть, его и не всякий компилятор скомпилирует? 1/3 вообще в языке C нет, и об этом написано у K&R, что нельзя в программе на языке С писать 1/3, это ошибка. Вы впариваете тут бред и чушь, и еще и спорите, понимая, что не правы.. Ваша программа на языке С ошибочная вообще. Помимо i386 есть еще и платформы ARM, Itanium, а помимо процессоров Intel и AMD есть еще много разных процессоров. Докажите сперва, что ваша программа, которая является как пример, является верной. где ваша выборка и результаты тестирования программы на парке, скажем из тысячи машине? и вообще вы кто такой по жизни, если спорите о простых вещах? Вы не программист вообще, а хз кто.

страница 184 Математический энциклопедический словарь
ДИСКРЕТНАЯ МАТЕМАТИКА - область математики, занимающаяся изучением свойств дискретных структур, к-рые возникают как внутри математики, так и в ее приложениях. К числу таких структур могут быть отнесены, напр. конечные группы, конечные графы, а также не-рые математич. модели преобразователей информации, конечные автоматы, машины Тьюринга и т.п. Это примеры структур финитного (конечного) характера.

страница 281 Математический энциклопедический словарь
КОНЕЧНЫЙ АВТОМАТ - матемтическая модель устройства с конечной памятью, преобразующего дискретную информацию.

страница 360
МАШИНА - абстрактное устройство, осуществляющее переработку информации. <...> Возникновение их связано с анализом понятия алгоритма, начавшегося в сер. 30-ч гг. 20 в., с развитием ЭВМ <...> Наибольшее распространение получили М., перерабатывающие дискретную информацию, типичными представителями к-рых являются конечный автомат и Тьюринга машина.

страница 597
ТЬЮРИНГА МАШИНА - название, закрепившееся за абстрактными вычислительными машинами некоторого точно охарактеризованного типа.

AMDBulldozer
01-12-2013, 10:47
mrcnn, обсуждали уже. Я привел шесть разных примеров, где равенство возможно и даже необходимо. Но потом удалил сообщения, чтобы не разводить флейм. Повторю еще раз: полностью согласен с уважаемым Iska. Перестаньте мыслить категориями 20-тилетнй давности. Воспринимайте "a" и "b" из задачи не как числа, а как объекты, между которыми определено отношение эквивалентности.
А уж что именно это за объекты - неважно. Я приводил пример и с вещественными числами для которых оператор == был переопределен и с матрицами и с вещественными для которых требовалось именно побитовое совпадение и даже с виртуальными машиными в которых такие числа как 1/3 или корень из двух представлены без какой-либо потери точности...
Сущность этих объектов не имеет никакого значения для контекста задачи.
Конечно, если Вы хотите сказать, что никакие объекты не могут быть эквивалентными.... Тогда Вам на философский форум.

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

pva
01-12-2013, 11:51
winston07,
В примере №2 у тебя из условия идут 3 стрелочки. Должно быть 2 ("да" и "нет").
Не все пути программы приводят к концу (на выводе заканчиваются стрелки).

В принципе примеры №1 и №3 могут пройти по прямой, без ветвлений (т..е. рисовать одним блоком). Но можно предусмотреть деление на ноль. Тогда появятся варианты.


(Начало)
|
/ Дано:x,a,b /
|
нет----------< x!=0? >----да
| |
| [ Часть1=a+(b/x) ]
| |
/ Часть1 нельзя вычислить / |
| |
| нет-----< 0<=x? >---------да
| | |
| / Часть2 нельзя вычислить / [ Часть2=sqrt(a+sqrt(x)) ]
| | |
| | [ y=(a+lg|b-x|)^2/(Часть1*Часть2) ]
| | |
| | / Результат: y /
| | |
-----------------------------------------
|
(Конец)

Забыл проверить в схеме (Часть1*Часть2)!=0. Обратите внимание, что есть 2 условия, разделённые блоком прямого прохода, причём результат вычисления в блоке может не использоваться (когда второй раз пойдём по ветке "нет". Можно оптимизировать условие в < 0<x? >


Добавлю к общему флуду:
Блок-схема предназначения для того, чтобы объяснить ход/особенности алгоритма (не вдаваясь в подробности реализации). Например, я лично рисовал блок-схемы узлов, которые программировал, чтобы объяснить их работу заказчику (при этом обучать его программированию не входило в планы). Блок-схемы надо уметь читать и писать. Для этого нужно решать "тупые" задачки в большом количестве. Ровно как обучение письму начинается с рисований "никому не нужных" закорючек.

Кстати, я заметил что компиляторы используют представление кода (3-adress-code) очень похожее на блок-схемы.

mrcnn
01-12-2013, 13:44
Машинный нуль (англ. Machine epsilon) — числовое значение, меньше которого невозможно задавать точность для любого алгоритма, возвращающего вещественные числа. Абсолютное значение "машинного нуля" зависит от разрядности сетки применяемой ЭВМ, от принятой в конкретном трансляторе точности представления вещественных чисел и от значений, используемых для оценки точности. [1]

В языке Си существуют предельные константы FLT_EPSILON и DBL_EPSILON называемые "машинными нулями" относительно вещественного значения 1.0. FLT_EPSILON - максимальное значение типа float и имеет значение 1E-5, DBL_EPSILON - максимальное значение типа double и имеет значение 1E-16. Сумма каждого из этих значений со значением 1.0 не отличается от -1.0.

Проблема машинного нуля в том, что два числа считаются одинаковыми, если они отличаются на величину, меньшую по модулю, чем машинный ноль.[источник не указан 1101 день]

При представлении чисел со знаком в обратных двоичных кодах существуют проблема[уточнить] наличия двух обратных кодов числа 0: «положительный нуль» и «отрицательный нуль».

http://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%88%D0%B8%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BD%D0%BE%D0%BB%D1%8C


Константы определены в заголовочном файле float.h
#define FLT_EPSILON 1.192092896e-07F /* smallest such that наименьшее, такое что 1.0+FLT_EPSILON != 1.0 */
#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that наименьшее, такое что 1.0+DBL_EPSILON != 1.0 */

Iska
01-12-2013, 13:58
ЭВМ оперирует структурами конечного типа. »
Подтверждаю.

1/3 не является в компьютере бесконечным. »
Согласен.

Выше приведен пример с числом 1.7, которое было преобразовано в 1.70000004768372 В 1/3 тоже добавляется в конец "мусор".. »
Не добавляется. Говоря Вашими словами, происходит отсечение «невмещающихся» цифр мантиссы.

Вы проверяете на платформе i386 а на других платформах, например встроенных систем, мобильных устройств и т.п. ваш пример может не сработать. ВАША ПРОГРАММА БЫЛА ПРОВЕРЕНА ЛИШЬ НА ВАШЕМ КОМПЬЮТЕРЕ, но не проверялась на других платформах. Докажите сперва, что ваша программа работает вообще ? Если она на вашем компьютере работает, это не значит, что она правильная. С чего вы решили, что у вас правильный код? Может быть, его и не всякий компилятор скомпилирует? »
1. Видите ли, язык C, коль уж о нём заговорили, создавался именно как переносимый язык, зависящий от платформы только библиотеками (другое дело, что на практике предпочли принести переносимость в жертву производительности).
2. «Докажите сперва, что ваша программа работает вообще ?» — если Вам недостаточно исходного кода, могу выложить бинарный файл, но, боюсь, Вас и это не убедит, что «программа работает».
3. Поищите у «не всякого компилятора» параметр, включающий поддержку стандарта ANSI.

Ваша программа на языке С ошибочная вообще. »
Чем именно «ошибочная вообще»?

1/3 вообще в языке C нет, и об этом написано у K&R, что нельзя в программе на языке С писать 1/3, это ошибка. »
На какой странице [Iska задумчиво мусолит второе издание K&R]?

Помимо i386 есть еще и платформы ARM, Itanium, а помимо процессоров Intel и AMD есть еще много разных процессоров. Докажите сперва, что ваша программа, которая является как пример, является верной. где ваша выборка и результаты тестирования программы на парке, скажем из тысячи машине? »
У Вас хромает логика: не требуется доказывать корректность работы приведённого приложения для всех мыслимых платформ. Для подтверждения факта ложности категоричного императива:
ибо никогда в лоб на плавающей точке равенства не будет...
достаточно найти одно опровержение. Я этот факт продемонстрировал.

Вы впариваете тут бред и чушь, и еще и спорите, понимая, что не правы.. »
Я знаю, что я прав. А Вам не хватает корректных аргументов, посему Вы судорожно хватаетесь то за одно, то за другое, то вовсе:
и вообще вы кто такой по жизни, если спорите о простых вещах?»
Зовут меня У, сам я вроде как отшельник… Человек я. Обычный человек.

Вы не программист вообще, а хз кто. »
Я и не утверждал нигде здесь, что я программист. Я уже лет двадцать как не программист.

Машинный нуль …

Константы определены в заголовочном файле float.h »
Говорю Вам в четвёртый раз: не надо убеждать меня в том, что я и сам хорошо знаю. Вы пытаетесь притянуть за уши определение, которое никак ни подтверждает, ни опровергает утверждения:
ибо никогда в лоб на плавающей точке равенства не будет...

mrcnn
01-12-2013, 14:29
У Вас хромает логика: не требуется доказывать корректность работы приведённого приложения для всех мыслимых платформ.

Хромает логика у вас, так как при полной индукции доказывается корректность для любого возможного случая. Но так как это является невозможным (нельзя физически проверить), для упрощения считают верным, если оно является корректным до некоторого заданного n. Но на самом деле оно является неверным. Нельзя считать что-то верным пока не произведена полная индукция.
В итоге пользователи начинают обращаться в тех поддержку из-за того, что у них программа не работает. Потому что программист не предусмотрел некоторые ситуации. Поэтому, для ПО постоянно выпускают обновления, заделывающие ошибки программистов.

Не добавляется. Говоря Вашими словами, происходит отсечение «невмещающихся» цифр мантиссы.
Иногда на калькуляторе (Citizen) при вычислениях 1.0 превращается в 0.99999(9), что является ошибочным, так как равенство на 1.0 точное, а не приближенное. У компьютера та же самая проблема. При точном равенстве компьютер оперирует приближенным представлениям в рамках эпсилон. В той теме на которую была дана ссылка задано точное равенство, а компьютер потерял точность, в итоге возникла ошибка, так как потерялся результат выборки из базы данных. Запрос на языке SQL был задан в следующем виде select * from table_name where val=1.7 а компьютер к точном 1.7. добавил "мусор" и начал оперировать не точным 1.7 а 1.70000004768372. Никакой мантиссы не было. Причем это все эмпирически, а не на словах. Возникла ошибка.

достаточно найти одно опровержение. Я этот факт продемонстрировал. »

Ваша программа, которую вы привели в качестве опровержения, является неправильной, ошибочной. Сомнительно, что она будет скомпилирована gcc компилятором.
В лоб числа с плавающей точкой не сравнивают из-за погрешности. И в архитектуре процессоров заложена определенная погрешность и точность. И инженеры, проектирующие процессоры, могут ошибаться.

mrcnn
01-12-2013, 15:08
Iska
В начале речь шла не о равенстве 1/3 и 1/3 а о сравнении a и b, а вы начали исходить из сравнения a и b при их равенстве сведя в итоге и a и b к 1/3. Конкретно, смотрите изображение IMG_20131130_121057.jpg топик стартера о блок схеме. Вы перевели рассуждение к ситуации, когда a и b аксиоматически являются одинаковы (и равными 1/3), что является неверным для IMG_20131130_121057.jpg Таким образом, вы подменили начальный тезис, сузив его. Причем Tau_0 прокомментировал изображение IMG_20131130_121057.jpg , а не вашу программу.

Последовательность событий:
1. 02:10, Вчера IMG_20131130_121057.jpg топик стартера о блок схеме к программе.
X = {
a / b + 1, если a > b,
a + 25, если a = b,
(a*b - 2) / a, если a < b;
}
2. 05:02, Вчера Tau_0 написал в "См. второй пример на ветвление, если a = b Он совсем не так прост..., ибо никогда в лоб на плавающей точке равенства не будет..."

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

В этой теме: http://www.rsdn.ru/forum/cpp.applied/1187492.flat в сообщении от 24.05.05 14:53 написано, что сравнивать вещественные числа нужно в некой окрестности и приведен код
bool isEq(double a, double b)
{
return abs(a-b)<epsilon.
}

Iska
01-12-2013, 15:33
Хромает логика у вас, так как при полной индукции доказывается корректность для любого возможного случая. »
Я опроверг конкретное утверждение. И попытки приплести сюда индуктивный вывод для его подтверждения уже ни к чему. Вы придумали себе нечто, и теперь с этим, Вами же придуманным, спорите.

Было сказано: «Для любых X верно Y». Я привёл опровержение, что Y верно отнюдь не для любых X. Но Вы с какого-то перепугу придумали себе и упорно требуете от меня доказательства «Для каждого X не верно Y».

Иногда на калькуляторе (Citizen) при вычислениях 1.0 превращается в 0.99999(9), что является ошибочным, »
О! Давайте ещё на счётах проверим, там уж точно приложение на C откажется работать. Вот будет доказательство так доказательство!
Первое ключевое слово — «при вычислениях». Второе — «при различных». Но, повторяю вновь: это никак не подтверждает, либо опровергает сделанного утверждения:
ибо никогда в лоб на плавающей точке равенства не будет...

Ваша программа, которую вы привели в качестве опровержения, является неправильной, ошибочной. Сомнительно, что она будет скомпилирована gcc компилятором. »
Вы опять забыли сказать чем именно она «является неправильной, ошибочной».
http://img22.imageshack.us/img22/8906/qzfg.png
http://img801.imageshack.us/img801/9194/h3mj.png
http://img811.imageshack.us/img811/6495/w30a.png

В лоб числа с плавающей точкой не сравнивают из-за погрешности. И в архитектуре процессоров заложена определенная погрешность и точность. И инженеры, проектирующие процессоры, могут ошибаться. »
Вы мне выше рекомендовали кое-что почитать. Я Вам тоже порекомендую. Есть такая книга: Программирование арифметических операций в микропроцессорах. Злобин В.К., Григорьев В.Л. (https://www.google.ru/search?q=%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8% D0%B5+%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85+%D0%BE%D0 %BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B9+%D0%B2+%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BF%D1%80%D0%BE%D1%8 6%D0%B5%D1%81%D1%81%D0%BE%D1%80%D0%B0%D1%85.+%D0%97%D0%BB%D0%BE%D0%B1%D0%B8%D0%BD+%D0%92.%D0%9A.,+%D 0%93%D1%80%D0%B8%D0%B3%D0%BE%D1%80%D1%8C%D0%B5%D0%B2+%D0%92.%D0%9B.) Ещё советского издания. И вот там на трёхстах страницах подробным образом изложены теория и, главное, практика программирования арифметических операций в двух наиболее известных микропроцессорах. С картинками, с блок-схемами. И рабочими листингами на ассемблере.

Сколько раз мне Вам повторять две вещи:
1. Я это знаю.
2. Это никак не доказывает истинности или ложности утверждения.

AMDBulldozer
01-12-2013, 15:35
Понятно, что человек хочет спорить просто ради самого факта спора. Безграмотные статьи из Вики и столь же безграмотные примеры какого-то Васи Пупкина для него пример абсолютной истины. На этом заканчиваю, не буду кормить тролля.

Iska: он просто хотел, чтобы Вы поставили точку после единицы (или после тройки). Иначе производится целочисленное деление и уже его результат преобразуется в вещественное число. При этом сам он опубликовал какой-то глупый код с непонятной функцией "abs", которая при наличии #include <stdlib.h> и отсутствии #include <cmath> будет целочисленной и стало быть все числа различающиеся не более, чем на 1 окажутся равны. А при наличии <cmath> код просто не скомпиллируется, поскольку не указана область видимости. Должно быть либо std::abs, либо явная отсылка к пространству имен в "using std::abs". Но такие "мелочи" его явно не волнуют.

Можете задать ему простой вопрос: написать программу вычисяющую машинный эпсилон (котогрый он вслед за Вики безграмотно называет "машинным нулем"). Интересно, как он это сделает без операции сравнения...

Iska
01-12-2013, 15:37
Iska
В начале речь шла не о равенстве 1/3 и 1/3 а о сравнении a и b, а вы начали исходить из сравнения a и b при их равенстве сведя в итоге и a и b к 1/3. Конкретно, смотрите изображение IMG_20131130_121057.jpg топик стартера о блок схеме. Вы перевели рассуждение к ситуации, когда a и b аксиоматически являются одинаковы (и равными 1/3), что является неверным для IMG_20131130_121057.jpg Таким образом, вы подменили начальный тезис, сузив его. Причем Tau_0 прокомментировал изображение IMG_20131130_121057.jpg , а не вашу программу. »
Я ничего не «подменял» и не «сужал». Коллега Tau_0 высказал утверждение. Вы этот категоричный императив поддержали. Я его опроверг.

Понятно, что человек хочет спорить просто ради самого факта спора. Безграмотные статьи из Вики и столь же безграмотные примеры какого-то Васи Пупкина для него пример абсолютной истины. На этом заканчиваю, не буду кормить тролля. »
Да, Вы правы. Поступлю так же.

Tau_0
01-12-2013, 16:42
Я его опроверг. »
Прежде,чем опровергать малость прочитайте... --- На эти грабли обычно студенты наступают или специалисты по логическому программированию, но не вычислители...

На уровне ликбеза и для уточнения посмотрите, что я имел в виду… Просто навскидку нашёл. Более каверзные случаи мне пока придумывать лениво, да и не по теме оно будет…

сравнение на равенство вещественных чисел, в последний раз, надеюсь (http://www.mql5.com/ru/forum/3872)
О сравнении действительных чисел. (http://bestcoding.info/topic111.html)
Ситуация, описанная в начале вполне нормальна. Т.е. при преобразовании десятичного целого в двоичное вещественное все равно добавится "белый шум". И неизвестно в каком из чисел он будет больше. Ну не бывает одинаковых вещественных чисел, и сравнивать е важно на равенство или на "больше-меньше" можно только с какой-то точностью. Поэтому условие должно выглядеть примерно так
Неправильнгое сравнение двух чисел типа double (http://forum.shelek.ru/index.php/topic,6441.0.html)

Iska
01-12-2013, 17:05
Tau_0, Вас тоже «кормить» не буду. Я полагал, мы с Вами разобрались. Оказывается нет. Повторять в пятый раз одно и то же я не стану. Всё, что изложено коллеге mrcnn, считайте теперь адресованным и Вам. На сим закончим.

AMDBulldozer
01-12-2013, 17:16
Ну не бывает одинаковых вещественных чисел »
#include <stdio.h>
main()
{
float x=1.,e=1.;
while( !( x+e == x ) ) e /= 2;
printf("%g\n",e);
}
Конструкция !( a == b ) использована вместо a != b исключительно с целью подчеркнуть равенство чисел как условие выхода из цикла. :wink:

Drongo
01-12-2013, 17:26
To All:

1. Помогите автору темы решить его вопросы и спорьте до посинения.
2. Если будет замечен переход на личности или троллинг опонента, такой пост будет выпиливаться.

mrcnn
01-12-2013, 17:40
Вы опять забыли сказать чем именно она «является неправильной, ошибочной». »
Она является ошибочной, так как в языке С нет дробей вида p/q. Не производит оперирование конструкциями вида 1/3. В K&R есть пример насчет перевода градусов по Фаренгейту в градусы по Цельсию, и там объясняется насчет деления чисел.
Помимо этого она является ошибочной, так как вы сравниваете вещественные числа в машинном представлении напрямую. Нельзя сравнивать вещественные a и b оператором ==.

winston07
01-12-2013, 18:16
вот как получилось
http://saveimg.ru/thumbnails/01-12-13/83d9f7de7bcf669e8589e019c0fadc4c.jpg (http://saveimg.ru/show-image.php?id=41e7ab055cf04400766cedf6928117ae)
http://saveimg.ru/thumbnails/01-12-13/12d820976a7fc155de6106c09b3b6d00.jpg (http://saveimg.ru/show-image.php?id=b710427c63f0cd96d2565b6af1f2c3ec)

Tau_0
01-12-2013, 18:29
с целью подчеркнуть равенство чисел как условие выхода из цикла. »
Вот вы какие настырные…:) --- а читать и думать ленитесь…:(
Вот мой последний аргумент в виде цитаты…

Побереги печень Не все так смертельно...
temp и sum - задаются ручками (типа sum=20.0 и temp=20.0), или это результат вычисления чего-либо? Судя по названию переменной temp - видимо результат вычисления...
Классика - с переменными действительного типа надо крайне осторожно проводить такие сравнения при вычислениях. Результат 1/3 и 3/9 может быть разным где-нибудь "в последнем знаке" и его не увидеть никогда...
Может привести к определенной точности (ну например до 6 знака) а потом уж и сравнивать...
Тема: Неправильнгое сравнение двух чисел типа double (Прочитано 12390 раз) (http://forum.shelek.ru/index.php/topic,6441.0.html)

Это я о том, что результат IF может быть как false, так и true --- сиё зависит от реализации… Только и всего.

Маленький вопрс на подумать --- чему равно с точностью до восьми знаков
1.0/3.0 + 1.0/3.0 + 1.0/3.0 =…???...
Пусть для простоты арифметика десятичная (на самом деле в машине она двоичная и от этого дополнительные фокусы,…)

PS Видимо оставанемся при своих и не будем напрягать недотыкомки…

AMDBulldozer
01-12-2013, 18:41
winston07, как-то не совсем понятно. По первой Вашей блок-схеме:
Какой смысл производить проверку значения X дважды? В первый раз Вы прерываете выполнение по равенству нулю, во -второй - по меньше или равно.
Очевидно, что если второе сравнение ложно, то и первое тоже ложно. Тем более, что второе сравнение Вы производите для определения существования вещественного корня, а в таких целях оно должно быть не "меньше или рано нулю", а просто "меньше".
С другой стороны, Вы не проверяете X на равенство B. Но если они равны, то разность |B-X| (у Вас ошибочно написано |B+X|) станет равна 0, а логарифм нуля это минус бесконечность.
На Вашем месте я сначала бы произвел обе эти проверки, а потом вычислил бы Y одной формулой. В противном случае, у Вас Y оказывается равен не всей дроби, а только её числителю.

Tau_0, если бы я был преподавателем и ко мне пришел бы студент с такими соображениями как у Вас. я сразу отправил бы его на пересдачу.
Это лет 30 назад можно было рассуждать об ошибках округления. Во времена парадигмы процедурного программирования. Тогда человеку даже поаплодировали бы. Но то время безвозвратно ушло и сегодня человек рассуждающий таким образом сильно напоминает питекантропа пытающегося рассказть об особенностях охоты на мамонтов при помощи камней и дубины.
Если человек начинает рассказ с того, что вещественные числа якобы не могут быть равны, ему возвращают зачетку и отправляют переучиваться. Поскольку таким высказыванием он, как минимум, демонстрирует полное непонимание разницы между алгоритмом и его программной реализацией.

Я могу пояснить, почему в Ваших рассуждениях имеется дефект. Только что автор темы опубликовал блок-схему, в которой не проверил X на равенство B перед вычислением выражения lg|b-x|. По Вашей логике, он поступил правильно - если считать, что обе величины являются действительными числами, как Вы предположили, то они, по Вашему утверждению, не могут быть равны (Вы это не смогли доказать, но упорно этой точки зрения ипридерживаетесь) и стало быть логарифм будет существовать в области действительных чисел. То есть и проверять незачем. Точка.
Послушавшийся Вас человек напишет заведомо неверную блок-схему. Во-первых, потому, что числа могут быть равны и это было наглядно продемонстрировано в программе вычисления "машиннного эпсилон". А во-вторых, если они даже окажутся НЕ равны, они могут быть настолько близки, что логарифм выйдет за пределы представления числа. Тогда надо проверять не только равенство чисел, но еще и переполнение/потерю значимости в процессе вычисления. И не только логарифма, но после любого действия. И т.д. и т.п.
В результате получается, что сделав акцент на одном аспекте, Вы полностью упускаете из вида сопутствующие. Вы скажете, что добавите все необходимые проверки в момент написания программы и что это не имеет отношения к собственно алгоритму? И будете правы. Именно об этом и речь - человек долже сначала сформулировать для себя основную идею, а детали реализации, к которым относятся и ошибки округления, оставить на потом.
Поймите, что говоря об ошибках округления Вы ни для кого Америку не открыли. Может быть это мы откроем её для Вас, когда расскажем, что с этими ошибками научились бороться несколько десятилетий назад.




© OSzone.net 2001-2012