Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Проблемы с float  [new]
denmat
Member

Откуда:
Сообщений: 3
SQL2008r2


declare
 @m float
 
set @m=150.20

select 
@m as a,                                   --150.2
CAST((@m * 100) as int) as b,      --15019
CAST((@m * 1000) as int) as c     --150200



Как с этим бороться? И почему именно при умножении на 100 вывалилась проблема?
Ясно, что лучше вообще избегать float, но у нас оно много где используется.
24 июл 12, 14:13    [12908390]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
denmat,

float не точный тип, почему конкретно именно 150.2 на 100 не может правильно умножить и преобразовать к инту сказать трудно, 150.1 или 150.3 нормально проходят. В этом примере, можно привести сначала флоат к децималу, а потом уже с ним выполнять действия.
24 июл 12, 14:27    [12908489]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Сид
Member

Откуда: Москва
Сообщений: 305
denmat,

потому что float - это весьма неточный тип данных, а приведение к int отсекает всю нецелую часть (а не округляет). Т.е. реально в переменной оказалось что-то типа 150.199999999 (цифру взял от балды).

Если так уж важен float, вместо int можно использовать decimal:

declare
 @m float
 
set @m=150.20

select 
@m as a,                                   --150.2
CAST((@m * 100) as dec(29,0)) as b,      --15020
CAST((@m * 1000) as dec(29,0)) as c     --150200


Но лучше изначально использовать decimal, особенно если в дальнейшем будет масса разных вычислений.
24 июл 12, 14:31    [12908510]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Сид
Member

Откуда: Москва
Сообщений: 305
upd: пример с cast( as dec(29,10)) работает именно для 150.2, но не факт, что будет работать для другого числа.
Избавьтесь от float и не насилуйте мозг))
24 июл 12, 14:34    [12908537]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
denmat
Member

Откуда:
Сообщений: 3
Избавиться дело не хитрое. Вот понять бы суть проблемы.
24 июл 12, 14:48    [12908665]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Glory
Member

Откуда:
Сообщений: 104760
denmat
Вот понять бы суть проблемы.

Проблема с понимаем арифметики чисел с плавующей запятой
24 июл 12, 14:54    [12908699]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Shakill
Member

Откуда: мск
Сообщений: 1882
denmat
Избавиться дело не хитрое. Вот понять бы суть проблемы.

потому что fioat - неточный тип, вам же сказали
declare @m float = 150.2
select cast(@m as decimal(20, 17))
24 июл 12, 14:57    [12908733]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
мимо
Guest
denmat,
В типе флоат (как впрочем и в децимале и иных ), в отличии от инта, хранится не само число, а некая совокупность аргументов для определенной функции, согласно которой и вычисляется искомое. На пальцах
24 июл 12, 15:53    [12909181]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18326
declare
 @m float
 
set @m=150.20

select 
@m as a,                                   --150.2
CAST((@m * 100) as int) as b,      --15019
CAST((@m * 1000) as int) as c    


select 
@m as a,                                   --150.2
@m * 100 as b,      --15020
@m * 1000 as c    --150200

Пофиг что флоат не точный тип. Это все равно явный косяк при конвертации.
24 июл 12, 16:22    [12909434]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18326
Вот так кстати работает. И всегда будет работать

declare
 @m float
 
set @m=150.20

select 
@m as a,                                   --150.2
CAST(round((@m * 100),0) as int) as b      --15020
24 июл 12, 16:24    [12909445]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
denmat
Member

Откуда:
Сообщений: 3
Я сделал
cast(@m numeric(18,2))
24 июл 12, 16:26    [12909457]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18326
Вот что нашел в БОЛе.

http://msdn.microsoft.com/ru-ru/library/ms187928(SQL.90).aspx
При преобразовании между типами данных с разными длинами дробных частей результат может усекаться или округляться. В следующей таблице описано это поведение.


Так что это задокументированный косяк.
24 июл 12, 16:28    [12909468]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18326
denmat
Я сделал
cast(@m numeric(18,2))
Это может не помочь, если это приведет к обрезанию.

Надо именно делать round до нужного количества. round гарантированно округлит по правилам.
24 июл 12, 16:29    [12909480]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Glory
Member

Откуда:
Сообщений: 104760
Deff
Пофиг что флоат не точный тип. Это все равно явный косяк при конвертации.

Косяк - это для тех, кто не знает принципов работы с такими числами.
А для остальных - это нормально.
24 июл 12, 16:34    [12909507]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18326
Glory
Deff
Пофиг что флоат не точный тип. Это все равно явный косяк при конвертации.

Косяк - это для тех, кто не знает принципов работы с такими числами.
А для остальных - это нормально.
Это задокументированный косяк. Не меняют его видимо ради совместимости с предыдущими версия. Когда-то так случайно получилось, так потом в документации и записали.
От того что я понимаю как устроен флоат, мне удобней работать не становится.
Это язык высокого уровня. При усечении дробной части вполне логично делать округление, а не обрезание.
24 июл 12, 16:47    [12909618]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Glory
Member

Откуда:
Сообщений: 104760
Deff
Это задокументированный косяк

Это не косяк. Есть разные стандарты работы с числами с плавающей точкой.

Deff
При усечении дробной части вполне логично делать округление, а не обрезание

Удобнее кому ?
24 июл 12, 16:51    [12909659]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
мимо
Guest
declare @float1 as float = 0.3
declare @float2 as float = 3
declare @float3 as float = 2
set @float1 =  (@float1/ @float2)*@float3 +255
set @float1 = (@float1-255)*@float2/@float3
select @float1


declare @d1 as decimal(18,8) = 0.3
declare @d2 as decimal(18,8) = 3
declare @d3 as decimal(18,8) = 2
set @d1 =  (@d1/@d2)*@d3 +255
set @d1 = (@d1-255)*@d2/@d3
select @d1
24 июл 12, 16:51    [12909667]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18326
Glory
Deff
При усечении дробной части вполне логично делать округление, а не обрезание

Удобнее кому ?
Встречный вопрос. А кому удобней от того, что иногда усекает, иногда обрезает?
Сделано ради быстродействия? - Сомневаюсь.
24 июл 12, 17:00    [12909752]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Massa52
Member

Откуда:
Сообщений: 382
Deff,

float используется для инженерных расчетов - там целые числа почти не используются. Ни один физик не оперирует целыми - у них там все приблизительно с точностью до ... И обычно операции с плавающей запятой выполняет специализированная часть проца. И если тебе нужно челое число - будь добр - округли с нужной точностью и переходи в область целых чисел. Не стоит мешать целое с плавающим - таково правило - если не хочешь проблем.
24 июл 12, 17:13    [12909864]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
iap
Member

Откуда: Москва
Сообщений: 47045
Deff
Это задокументированный косяк. Не меняют его видимо ради совместимости с предыдущими версия. Когда-то так случайно получилось, так потом в документации и записали.
Стандарт IEEE 754 :))
24 июл 12, 17:17    [12909895]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4256
Massa52
Deff,

float используется с точностью до ... .


#define FLT_EPSILON 1.192092896e-07F /* smallest such that 1.0+FLT_EPSILON != 1.0 */
25 июл 12, 00:12    [12911217]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с float  [new]
Glory
Member

Откуда:
Сообщений: 104760
Deff
Встречный вопрос. А кому удобней от того, что иногда усекает, иногда обрезает?
Сделано ради быстродействия? - Сомневаюсь.

Вы почему думаете, что разрядность операций и промежуточных результатов вещественных чисел у SQL Server бесконечна.
А также думаете, что неявное преобразование одних типов в другие делается по вашим правилам.
Вот умножьте массу солнца на массу электрона, используя только разрешенную в MSSQL точность для веществеееых чисел.
25 июл 12, 13:04    [12913450]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить