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

проверка на целочисленность


вообще не понимаю, что происходит.
вот скрипт
declare @t table (a float)
insert into @t values (10.00), (12.5), (0.99999999999999999999999999999999)

select a, floor(a)
from @t
where a <> floor(a)


выдает:
a	(No column name)
10	9
12,5	12


1) почему floor выдает 9?
2) почему строка попадает в выборку?

дальше интереснее.
не будем вставлять в таблицу последнее значение, вроде как оно и ни при чем.
declare @t table (a float)
insert into @t values (10.00), (12.5)--, (0.99999999999999999999999999999999)

select a, floor(a)
from @t
where a <> floor(a)

а результат поменялся:
a	(No column name)
12,5	12


...почему-то мне напоминает последствия вылазивания за границы массива в процедурном программировании...
2 окт 12, 17:19    [13257447]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
declare @t table (a numeric (18,10))
2 окт 12, 17:23    [13257474]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
для тупых
Guest
ну и в чем прикол-то?
если сменить float на numeric(18,10), ситуация не воспроизводится!
почему, убрав 1 левое значение, которое и так не попадало в выборку,
меняется число возвращаемых запросом строк?
2 окт 12, 17:29    [13257523]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Jovanny
Member

Откуда:
Сообщений: 1196
А вот такой расклад
declare @t table (a float)
insert into @t values (10.00), (12.5), (0.999999999999999)

select a, floor(a)
from @t
where a <> floor(a)


выдаёт
a	             (No column name)
12.5               12
0.999999999999999  0
2 окт 12, 17:33    [13257557]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
для тупых
Guest
ну а я про что.
впечатление, как будто последнее значение "переполняет" таблицу и у него крыша едет.
убрать последнее значение или обрезать его, - и сразу начинает работать как положено
2 окт 12, 17:41    [13257607]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
float
2 окт 12, 17:47    [13257641]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
для тупых
Guest
Maxx
float

очень информативно.
а главное, и до этого прочитано.
и как же это объясняет:
почему, убрав 1 левое значение, которое и так не попадало в выборку,
меняется число возвращаемых запросом строк?


тупые для того и спрашивают у умных, что прочитанное на тему им свет не пролило
2 окт 12, 17:54    [13257692]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Валдай
Member

Откуда:
Сообщений: 113
для тупых,

declare @t table (a float(22), b float)
insert @t
select cast(0.99999999999999 as float), cast(0.99999999999999 as float)

select * ,
         Precision_a = SQL_VARIANT_PROPERTY(a,'Precision') ,
         Precision_b = SQL_VARIANT_PROPERTY(b,'Precision') 
from @t


так понятней?
нет?

bol
float[(n)]
n 1-24 - 7 digits
n 25-53 - 15 digits
считаем цифры :)
2 окт 12, 18:02    [13257743]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Ю2008
Guest
Непонятно, причем здесь цифры:

declare @t table (a float)
insert into @t values (10.00), (12.5),  (0.999999999999999), (0.99999999999999999999999999999999)

select a, floor(a) fa, CAST(a as decimal(38,35)) af
from @t

delete from @t

insert into @t values (10.00), (12.5), (0.999999999999999) --,  (0.99999999999999999999999999999999)

select a, floor(a) fa, CAST(a as decimal(38,35)) af
from @t


a fa af
10 9 9.99999999999999820000000000000000000
12.5 12 12.49999999999999800000000000000000000
0.999999999999999 0 0.99999999999999893000000000000000000
1 1 1.00000000000000000000000000000000000


a fa af
10 10 10.00000000000000000000000000000000000
12.5 12 12.50000000000000000000000000000000000
0.999999999999999 0 0.99999999999999905000000000000000000


В каком случае floor(a) (где a=10.00) вычислилось правильно?
2 окт 12, 18:32    [13257920]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
для тупых
Guest
Валдай,

нет, не стало мне понятнее.
хоть я пихаю туда с тремя девятками, хоть со ста тремя девятками,
по умолчанию точность у float 53.
и этот код подтверждает это.
declare @t table (a float)
insert into @t values (10.00), (12.5)--, (0.99999999999999999999999999999999)

select a, 
       floor(a) as floor_a, 
       SQL_VARIANT_PROPERTY(a,'Precision') as float_prec, 
       SQL_VARIANT_PROPERTY(floor(a),'Precision') as floor_res_prec
from @t


a	floor_a	float_prec	floor_res_prec
10	10	53	53
12,5	12	53	53



declare @t table (a float)
insert into @t values (10.00), (12.5), (0.99999999999999999999999999999999)

select a, 
       floor(a) as floor_a, 
       SQL_VARIANT_PROPERTY(a,'Precision') as float_prec, 
       SQL_VARIANT_PROPERTY(floor(a),'Precision') as floor_res_prec
from @t


a	floor_a	float_prec	floor_res_prec
10	9	53	53
12,5	12	53	53
1	1	53	53


а вот почему наличие числа с кучей девяток в таблице меняет результат функции floor для остальных из той же таблицы,
мне так и неясно
2 окт 12, 18:33    [13257924]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Валдай
Member

Откуда:
Сообщений: 113
для тупых,

макчсимум 15 значащих цифр.. если больше - округление
select 
  cast(9.99999999999999 as float)
, cast(10.99999999999999 as float)
, cast(0.999999999999999 as float)
, cast(0.9999999999999999 as float)


т.е 0.9999999999999999 = 1
и floar(0.9999999999999999) = floor(1)
2 окт 12, 18:44    [13257964]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
для тупых
Guest
Валдай
для тупых,

макчсимум 15 значащих цифр.. если больше - округление
select 
  cast(9.99999999999999 as float)
, cast(10.99999999999999 as float)
, cast(0.999999999999999 as float)
, cast(0.9999999999999999 as float)


т.е 0.9999999999999999 = 1
и floar(0.9999999999999999) = floor(1)


не, не, я тупее, чем вы думаете.
оставим в покое девятки и вернемся к 10.00
получите мне еще каким-либо способом, cast-ом к чему-нибудь,
чтоб на входе floor было 10.00, а на выходе floor <какие-то cast-ы 10.00 as ...> = 9
2 окт 12, 18:59    [13258009]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
invm
Member

Откуда: Москва
Сообщений: 9720
declare @t table (a float, v_BaseType sql_variant, v_Precision sql_variant, v_Scale sql_variant);
insert into @t
 select
  v, sql_variant_property(v, 'BaseType'), sql_variant_property(v, 'Precision'), sql_variant_property(v, 'Scale')
 from
  (values (10.00), (12.5), (0.99999999999999999999999999999999)) t(v);

select
 a, cast(a as numeric(34,20)), v_BaseType, v_Precision, v_Scale
from @t;
go

declare @t table (a float, v_BaseType sql_variant, v_Precision sql_variant, v_Scale sql_variant);
insert into @t
 select
  v, sql_variant_property(v, 'BaseType'), sql_variant_property(v, 'Precision'), sql_variant_property(v, 'Scale')
 from
  (values (10.00), (12.5), (0.99999999999999)) t(v);

select
 a, cast(a as numeric(34,20)), v_BaseType, v_Precision, v_Scale
from @t;
go

declare @f float;

select @f = cast(10.0 as numeric(34,32));
select @f, cast(@f as numeric(34,32));

select @f = cast(10.0 as numeric(16,14));
select @f, cast(@f as numeric(34,32));
2 окт 12, 19:12    [13258055]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Ю2008
Guest
invm,

Еще больше непонятно:
declare @f float;

select @f = cast(10.0 as numeric(16,14));
select @f, cast(@f as numeric(38,36));

select @f = cast(10.0 as numeric(34,32));
select @f, cast(@f as numeric(38,36));

select @f = cast(10.0 as numeric(37,35));
select @f, cast(@f as numeric(38,36));
@f cast
10 10.000000000000000000000000000000000000
10 9.999999999999998200000000000000000000
10 10.000000000000000000000000000000000000

Как часто, и в зависимости от чего, меняются "показания"?
Получается, что стабильности можно добиться только искусственно ограничивая точность?
2 окт 12, 21:34    [13258439]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
invm
Member

Откуда: Москва
Сообщений: 9720
Ю2008,

http://msdn.microsoft.com/en-US/library/ms191530(v=SQL.90).aspx
For the decimal and numeric data types, SQL Server considers each specific combination of precision and scale as a different data type. For example, decimal(5,5) and decimal(5,0) are considered different data types.

In Transact-SQL statements, a constant with a decimal point is automatically converted into a numeric data value, using the minimum precision and scale necessary. For example, the constant 12.345 is converted into a numeric value with a precision of 5 and a scale of 3.

Converting from decimal or numeric to float or real can cause some loss of precision. Converting from int, smallint, tinyint, float, real, money, or smallmoney to either decimal or numeric can cause overflow.
2 окт 12, 22:01    [13258550]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Glory
Member

Откуда:
Сообщений: 104751
для тупых
выдает:
a	(No column name)
10	9
12,5	12



1) почему floor выдает 9?
2) почему строка попадает в выборку?

На SQL2000-8.00.2066 (Intel X86) выдается только строка 12,5 12

А глючит конструкция insert into @t values (10.00), (12.5), (0.99999999999999999999999999999999)
потому что с
insert into @t values (10.00)
insert into @t values (0.99999999999999999999999999999999)
insert into @t values (12.5)

все тоже корректно и на SQL2008

Причина скорее всего в том, что
insert into @t values (10.00), (12.5), (0.99999999999999999999999999999999)
выполняется по приниципу UNION
Т.е. 10.00 UNION 12.5 UNION 0.99999999999999999999999999999999
что приводит еще к каким то усечением данных. Из-за того, что тип данных результирующего столбца определяется по 1-му значению.

Сообщение было отредактировано: 3 окт 12, 10:29
3 окт 12, 10:25    [13259832]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Glory
Member

Откуда:
Сообщений: 104751
По-моим предположением при values (10.00), (12.5), (0.99999999999999999999999999999999)
все значения приводятся к numeric(34,32) и только потом уже конвертируются во float
А при отдельных
values (10.00)
values (12.5)
values (0.99999999999999999999999999999999)
каждая из констант приводится к разным numeric
И соответственно получаем разные усечения результатов при конвертации во float
А результат floor лишь только следствие этих усечений
3 окт 12, 10:35    [13259914]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Glory
Member

Откуда:
Сообщений: 104751
declare @t table (id int identity, a float)
insert @t select cast(10.00 as numeric(5,2))
insert @t select cast(10.00 as numeric(34,32))
select * from @t

на SQL2000 дает
1 10.0
2 9.9999999999999982

на SQL2008R2 дает
1 10
2 10

что там все таки поменялось в методике усечения результатов при конвертации типов. Потому что во втором случае эти "10"-ки чем то все таки отличаются
3 окт 12, 10:58    [13260083]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Sevolod
Member

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

Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (Intel X86)

id          a                                                     
----------- ----------------------------------------------------- 
1           10.0
2           9.9999999999999982
3 окт 12, 11:48    [13260547]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Microsoft SQL Server 2008 (SP1) - 10.0.2776.0 (X64) May 14 2010 01:53:15 Copyright (c) 1988-2008 Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 5.2 <X64> (Build 3790: Service Pack 2)
declare @t table (id int identity, a float)
insert @t select cast(10.00 as numeric(5,2))
insert @t select cast(10.00 as numeric(34,32))
select * from @t

id	a
1	10
2	10
3 окт 12, 11:50    [13260559]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
iap
Member

Откуда: Москва
Сообщений: 47083
Glory
Из-за того, что тип данных результирующего столбца определяется по 1-му значению.
Ошибочка!
Это имена полей определяются по первому SELECTу UNIONа
А тип определяется наибольшим приоритетом типа поля среди всех SELECTов.
http://msdn.microsoft.com/ru-ru/library/ms180026(v=sql.100).aspx
Если типы данных различаются, то получившийся тип данных определяется на основе правил очередности типов данных.
3 окт 12, 12:08    [13260726]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
для тупых
Guest
Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (X64)   Jun 17 2011 00:54:03   Copyright (c) Microsoft Corporation  Enterprise Edition (64-bit) on Windows NT 6.0 <X64> (Build 6002: Service Pack 2) (Hypervisor) 


проверяю догадку про приведение типов.
привожу в явном виде 1 к numeric(28,26)
select cast(1 as numeric(28,26))

(No column name)
1.00000000000000000000000000

никакого искажения

теперь использую скрипт invm
declare @t table (a float, v_BaseType sql_variant, v_Precision sql_variant, v_Scale sql_variant);
insert into @t
 select
  v, sql_variant_property(v, 'BaseType'), sql_variant_property(v, 'Precision'), sql_variant_property(v, 'Scale')
 from
  (values (10.0), (0.12345678901234567890123456), (1)) t(v);

select
 a, FLOOR(a),cast(a as numeric(38,36)), v_BaseType, v_Precision, v_Scale
from @t;
go


a	(No column name)	(No column name)	v_BaseType	v_Precision	v_Scale
10	10	10.000000000000000000000000000000000000	numeric	28	26
0,123456789012346	0	0.123456789012345670000000000000000000	numeric	28	26
1	0	0.999999999999999760000000000000000000	numeric	28	26


значит, исказилось при переводе numeric(28,26) -> float

теперь пробую менять число знаков после запятой, что получаю:
до 25 знаков не искажает, т.е. перевод из numeric(*,24) -> float проходит без проблем.
начиная с numeric(*,25) искажает.
и верно такое: перевод целое -> numeric(*,*) -> float (24) тоже не искажает, даже если в numeric scale от 25 до 36
почему именно на 25 свет клином сошелся?
3 окт 12, 12:31    [13260925]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Glory
Member

Откуда:
Сообщений: 104751
для тупых
почему именно на 25 свет клином сошелся?

BOL - CAST and CONVERT
When you convert data types that differ in decimal places, sometimes the result value is truncated and at other times it is rounded.
3 окт 12, 12:37    [13260957]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Glory
Member

Откуда:
Сообщений: 104751
Результаты тестов (из данной темы)


declare @t table (id int identity, a float)
insert @t select cast(10.00 as numeric(5,2))
insert @t select cast(10.00 as numeric(34,32))
select * from @t

на версиях
SQL Server 2000 - 8.00.2066 (Intel X86) 
SQL Server 2008 R2 (SP1) - 10.50.2500.0 (Intel X86)

результат
1 10.0
2 9.9999999999999982



на версиях
SQL Server 2008 (SP1) - 10.0.2776.0 (X64) 
SQL Server 2008 R2 (RTM) - 10.50.1600.1 (Intel X86)   
SQL Server 2008 R2 (SP1) - 10.50.2500.0 (X64)

результат
1 10
2 10
3 окт 12, 12:46    [13261049]     Ответить | Цитировать Сообщить модератору
 Re: загадочность на тему float  [new]
Ю2008
Guest
Glory
declare @t table (id int identity, a float)
insert @t select cast(10.00 as numeric(5,2))
insert @t select cast(10.00 as numeric(34,32))
select * from @t

на SQL2000 дает
1 10.0
2 9.9999999999999982

на SQL2008R2 дает
1 10
2 10

что там все таки поменялось в методике усечения результатов при конвертации типов. Потому что во втором случае эти "10"-ки чем то все таки отличаются

Отличаются (SQL Server 2008 R2 (RTM)):
declare @t table (id int identity, a float)
insert @t select cast(10.00 as numeric(5,2))
insert @t select cast(10.00 as numeric(34,32))
select *, cast(a as numeric(5,2)) [52], cast(a as numeric(34,32)) [3432], floor(a) fa from @t

id	a	52	3432					fa
1	10	10.00	10.00000000000000000000000000000000	10
2	10	10.00	9.99999999999999820000000000000000	9
3 окт 12, 12:52    [13261104]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить