Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: [Visual Studio, C++] проблема с типом double  (Прочитано 26785 раз)
0 Пользователей и 3 Гостей смотрят эту тему.
Kotiara
Постоялец

ua
Offline Offline

« : 14-08-2009 17:11 » 

сейчас у меня стоит VC 2005 уже давненько заметил весма странную проблему связанную с работой debugger-а с типос double простой пример есть число 846.346 я хочу снять с него целую часть отнимаю от него 846 теоритически у меня должен получится результат 0,346 вместо этого получается 34600000000643 короче первая же мат операция портит исходное число. По началу мне показалось это странноватым но я списал это на некачественный взлом или допустим плохую совместимость с АМД но впринципе меня это не очень трогало
при отладке мне главное проверить логику а не правильность работы калькулятора исправлял если надо было в ручную или дописывал заглушку но сейчас началась какаято совсем лажа у меня уже и релизы начали работать также. Если кто знает в чом тут дело подскажите пожалуйста насчот процессора или самой проги сомнительно чтобы дело было в них с момента когда впервые заметил я сменил несколько компиляторов(устанавливал с других дисков версии теже 6,0 и 2005) и полностью сменил железо на компе процессор АМД но поколение уже другое.
Вот я и думаю может это какаято хитрая настройка компилятора по умолчанию неправильно установленна?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 14-08-2009 17:47 » 

результат получается

0.34600000000000364

может, у тебя нолик в начале не виден, а глюки - это из совсем другой области ? Улыбаюсь
Записан

Kotiara
Постоялец

ua
Offline Offline

« Ответ #2 : 14-08-2009 18:24 » new

я прошу прощения я действительно забыл нолик там поставить число и правда получается 0.34600000000000364 но проблемма от этого не решается Здесь была моя ладья...
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 14-08-2009 18:26 » 

эээ... тогда я не пойму, в чём проблема то заключается ?
Записан

Kotiara
Постоялец

ua
Offline Offline

« Ответ #4 : 14-08-2009 18:32 » 

проблемма в том что последних трёх разрядов там небыло и посути с точки зрения матиматики 846.346-846=0,346 а не 0.34600000000000364  по тому как при дальнейших мат действиях ситуация сильно усугубляется и число становится непригодно до крайней степени!
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 14-08-2009 18:33 » 

ну это погрешности вычислений.

наверное помогут функции из файла
#include "math.h"

(сам не пользовался ими, за качество надо проверить Улыбаюсь )

Код:
Splits a floating-point value into fractional and integer parts.

double modf(
   double x,
   double *intptr
);
float modf(
   float x,
   float *intptr
);  // C++ only
long double modf(
   long double x,
   long double * intptr
);  // C++ only
float modff(
   float x,
   float *intptr
);
Parameters
x
Floating-point value.
intptr
Pointer to stored integer portion.
Return Value
This function returns the signed fractional portion of x. There is no error return.

Remarks
The modf function breaks down the floating-point value x into fractional and integer parts, each of which has the same sign as x. The signed fractional portion of x is returned. The integer portion is stored as a floating-point value at intptr.

modf has an implementation that uses Streaming SIMD Extensions 2 (SSE2). See _set_SSE2_enable for information and restrictions on using the SSE2 implementation.

C++ allows overloading, so you can call overloads of modf. In a C program, modf always takes two double values and returns a double value.
Записан

Kotiara
Постоялец

ua
Offline Offline

« Ответ #6 : 14-08-2009 18:42 » 

спасибо за подсказку попробую когда преустановлю VC после н количества попыток както продавить код на ощибки он сивсем сбрендил и стал самороизвольно решать какие действия ему делать а какие можно пропустить а последний прикол это вместо инициализации переменной типа инт он начинает преписовать данные из строки с которой в данном контэйнере воопще некаких действий не производится Не может быть...
Записан
Kotiara
Постоялец

ua
Offline Offline

« Ответ #7 : 14-08-2009 18:46 » 

кроме того раньше в рабочей версии програмы всё работало нормально глюк наблюдался только при отладке по этому и неособо волновался логику проверил а ошибок в расчотах в рабочей всё равно небыло
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 14-08-2009 18:50 » 

в отладке курсор скачет по строкам не того файла - это у VC6 глюк такой есть Улыбаюсь Проявляется то ли при использовании шаблонов, то ли просто при отладке файлов, которые не в корне проекта лежат, а где то далеко. На самом деле всё правильно отрабатывается, только курсор показывается не там, где он в реальности находится. Можно попробовать alt+F8 - в ассемблерном листинге потрассировать, там иногда тоже можно знакомые имена встретить ))
Записан

Kotiara
Постоялец

ua
Offline Offline

« Ответ #9 : 14-08-2009 19:07 » 

ну во первых у меня сейчас VC 2005 а во вторых он непросто нетак как надо скачит он ещо и меняет значения в переменных которых он даже касатся не должен
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 14-08-2009 19:17 » 

подозреваю, что дело не в студиях у тебя, а в некорректном использовании памяти или ещё чего нибудь )
Записан

Kotiara
Постоялец

ua
Offline Offline

« Ответ #11 : 14-08-2009 19:34 » 

да я тоже подозревал какието апаратные проблеммы но кроме студии всё работает коректно если бы чтото с пямятью или процессором у меня другие приложения вылетали бы.Я бумаю как максимум это какаято не совместимость софта с железом темболее что студия старше ядра моего процессора но даже при этом вопрос остаётся открытым почему этот же глюк проявлялся и до обновления апаратной части? тоесть на другом проце и оперативе да и материне а если вы имели виду что я чото с указателями накрутил так вопервых я это дело первым делом проверял а во вторых программа простейшая я просто в новом проэкте решил дописать и от тестить функцию одну единственную просто чтобы не ковырять уже готовую прогу и указателей там всего 2 и оба ипользуются в других местах программы
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 14-08-2009 19:40 » 

да, я думаю, что железо и софт тут ни при чём, а именно ты накрутил с указателями Улыбаюсь У меня так бывало по первяку, похожие глюки вылезали
Записан

Kotiara
Постоялец

ua
Offline Offline

« Ответ #13 : 14-08-2009 20:07 » 

нет дело походу совсем не в указателях ну путать там действительно нечего а кроме того компилятог действительно крякнулся даже после переустановки работает не правильно перестал открывать старые проэкты хотел на точно работающей проге дебагер проверить не открывает половину того что в нём написано было какаято в конец непонятная штука прийдётся его наверное ещо разок снести только перед переустановкой основательно вычестить систему кстати вы незнаете VS под линуксом на вайне работать будет просто мне быстрее в линукс перейти и там ещо разок поставить чем щас улиь для удаления прог качать устанавливать и учится пользоватся
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 14-08-2009 20:16 » 

про линукс я ничего не знаю, не пользовался.
А ты вирусов не нахватал, кстати ?
Записан

Kotiara
Постоялец

ua
Offline Offline

« Ответ #15 : 14-08-2009 20:51 » 

ну насчот вирусов чисто в теории конечно мог у сеня какраз гдето в обед антивирус в очередной раз помер но я сегодня и по инету толком не лазял не до того было Улыбаюсь и както странно что только одно приложение поражено и больше никаких лаж. Кроме того это не обьясняет того почему теже проблеммы были к примеру вчера или пол года назад я имею виду с дробными числами хотя моглобы до какойто степени обьяснить почему они перекинулись на готовые прилоения из дебагера. В любом случае я решил попробовать привентить VS к линуксу я бы и винду давно снёс если бы был уверен что там всё работать будет коректно а если получится то и проблеммы с вирусами отпадут сами по сибе Отлично
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #16 : 15-08-2009 07:02 » 

Kotiara, Скорее всего студия будет тянуть кучу библиотек в придачу. Замучаешся отлавливать зависимости. Лучше поставить виртуальную машину и на ней запустить чистую винду. А там уже установить студию. Хотя если ты не используеш специфику винды. То тоже самое можно в принципе сделать и для GCC, используя Code:Block в качестве IDE например.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 15-08-2009 07:40 » 

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

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #18 : 17-08-2009 03:36 » 

а также о невозможности выразить некоторые числа в double
Записан

Странно всё это....
Kotiara
Постоялец

ua
Offline Offline

« Ответ #19 : 27-08-2009 21:52 » 

Dimka и LogRus блогадорю я об этом уже начитался дальше некуда даже поправил проблемму теперь лажа осталась только в дебагере я просто переставил студию начисто и в новый проэкт впихнул текст проги всё заработало а насчот точности то погрешность меня вполне устраевает если она не выходит за рамки. А проблеммы в дебагере как были так и остались я имеюя виду вот что если взять число А и умножить его Н раз на число Б затем результат этиже Н раз поделить на Б то результат будет отличатся конечно от А это и есть накопление погрешности но если сделать так Х=А*Б то погрешность в иксе относительно опсолютной точности должна составлять ту самую погрешность если теперь сделать А=Х*Б то погрешность в А относительно опсолютного результата конкретно этого вычисления не должна превышать установленную в стандарте но если я проделываю хотябы 3 вычисления с одной переменной при этом сохраняя в ней результаты переменных то после третьего получается что точность последнего вычисления относительно обсолютного результата уже невписывается в стандарт который сам майкрософт определил как 15 знаков гарантированной точности А черт его знает...
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #20 : 28-08-2009 02:50 » 

блин, используй запятые и точки, а то пока прочитал - весь мозг поломал, а смысл написанного не понятен
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #21 : 28-08-2009 04:25 » 

Kotiara, 15 значащих цифр может содержать число, но нет никакой гарантии, что дробная часть числа будет отражена корректно в последней интересующей тебя цифре и это не стандарт MS это свойство чисел с плавающей точкой, на этом всё.

8.123 в дабле хранится, как 8.1229999999999993, и точнее оно никогда не будет, другое дело, что при выводе на экран функции преобразования числа в строку могу тебе набрехать, т.е. они увидят, что вероятнее всего ту лежит 8.123 и на экран покажут именно это. естественно математические операции это не функции преобразования в строку и они видят, то что видят

так что гарантированных 15 знаков, у тебя есть, НО они не такие точные, как хочется.
Записан

Странно всё это....
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 28-08-2009 12:25 » 

Тут ещё надо учитывать, что в двоичном представлении дробная часть числа разлагается по степеням двойки: 0.5, 0.25, 0.125, 0.0625 и т.д. У double на мантиссу отводится 52 бита. Именно потому декларируется точность 15 десятичных знаков, что 2^-52 даёт десятичное число порядка -16 степени.

Но при арифметических операциях верные значащие цифры и погрешности нужно считать в двоичных, а не в десятичных числах. Потому что на верность одной значащей цифры десятичного числа влияет верность многих двоичных цифр одновременно. Например, при формировании 1-го десятичного разряда после запятой отвечают, как видно из последовательности степеней двойки, первые 3 числа последовательности, т.е. первые 3 бита. Неверность 3-го бита приводит к неверности всего десятичного разряда.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Kotiara
Постоялец

ua
Offline Offline

« Ответ #23 : 28-08-2009 15:35 » 

Вы наверное правы в том что нельзя говорить об обязательной точности, я просто хотел сказать что при пользовании дебагера создаётся такое впечатление что погрешность накапливается не на число а именно на переменную, вроде того чем больше раз я ею пользуюсь тем больше в ней погрешность даже если значение в неё было залито свежее. Но посути это уже неочень важно в экзэшнике всё работает нормально так что сейчас это просто банальное любопытсво. Кстати насчот любобытства а ктонебуть знает где корни этой проблеммы? В смысле почему используется именно эта система вычислений, ведь наверняка можно былобы придумать чтото более точное Не понял
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #24 : 28-08-2009 15:51 » 

Kotiara, проблема заключается в том, что процессоры на сегодняшний день - двоичные. Вот когда придумают элемент памяти с 10 стабильными состояниями, вот тогда заживём как в сказке Улыбаюсь)
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 28-08-2009 16:01 » 

Как будто замена системы счисления что-нибудь изменит Улыбаюсь

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

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

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #26 : 28-08-2009 16:12 » 

Алексей1153++, процессоры-то двоичные, но ещё в i8086 включены команды двоично-десятичной арифметики (говорят, по требованию финансистов, которые боялись двоичных чисел и требовали аппаратной поддержки десятичной арифметики) Улыбаюсь

Есть BCD формат - каждые 4 бита используются для хранения 1 десятичного разряда.
Есть ASCII формат - каждый байт используется для хранения 1 десятичного разряда.

Смотреть можно в сторону инструкций: AAA, AAD, AAM, AAS, DAA, DAS Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #27 : 28-08-2009 16:26 » 

это упакованный и неупакованный BCD форматы, если правильно помню ) Я применял их именно в кр580, кстати. Но C++ то ими не пользуется Улыбаюсь
Записан

RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #28 : 28-08-2009 18:28 » 

BCD в FPU используется только для загрузки/выгрузки, а хранение в стеке все равно в плавающем формате 80 бит и точность вычислений определяется настройками FPU - 32/64/80 (думаю, что на практике вряд ли используется не 80). В плавающем 80-битном  выделено 64 бита  на мантису - 19 десятичных цифр, BCD - 18 цифр. По идее, должно хватить.
Кстати, BCD - целочисленный формат.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines