gotchasqlMinor
Why does SQL Server convert floats to scientific notation?
Viewed 0 times
whysqlconvertscientificnotationdoesserverfloats
Problem
I came across some weird behavior: While passing a float value into a varchar column, the values are getting converted from integers into scientific notation, and it's that scientific notation that gets stored as a string.
results look like this:
1.49559e+006
Scientific notation stored as a string. It's easy enough to work around by casting as int:
But the whole thing has me scratching my head.
Question: What is it about floats that stores them this way?
if OBJECT_Id('tempdb..#whydis') is not null begin drop table #whydis end
if OBJECT_Id('tempdb..#ImSeriously') is not null begin drop table #ImSeriously end
create table #whydis (bigID float)
create table #ImSeriously (bigID varchar(255))
insert into #whydis(BigID)
values(1495591),
(1495289),
(1495610),
(1495611),
(1495609),
(1495592),
(1495686)
INSERT INTO #ImSeriously (bigID)
SELECT BigID from #whydis
select * from #ImSeriouslyresults look like this:
1.49559e+006
Scientific notation stored as a string. It's easy enough to work around by casting as int:
INSERT INTO #ImSeriously (bigID)
SELECT cast(BigID as int) from #whydisBut the whole thing has me scratching my head.
Question: What is it about floats that stores them this way?
Solution
This is documented under
For a float or real expression, style can have one of the values shown in the following table. Other values are processed as 0.
Value
Output
0 (default)
A maximum of 6 digits. Use in scientific notation, when appropriate.
1
Always 8 digits. Always use in scientific notation.
2
Always 16 digits. Always use in scientific notation.
3
Always 17 digits. Use for lossless conversion. With this style, every distinct float or real value is guaranteed to convert to a distinct character string.
Applies to: SQL Server (Starting in SQL Server 2016 (13.x)) and Azure SQL Database.
126, 128, 129
Included for legacy reasons; a future release could deprecate these values.
You are using an implicit conversion from float to varchar(255), which implicitly uses style 0. Your floats all have more than six digits, so they are represented in scientific notation.
Floating point numbers are often shown in scientific notation. These types are used when range is more important than absolute precision. The numbers quickly become unwieldy in other formats. Scientific notation also helps to emphasise the limited precision.
You might like to use
Both produce the output:
For float, integers from −253 to 253 (−9,007,199,254,740,992 to 9,007,199,254,740,992) can be exactly represented. For real, integers between −16777216 and 16777216 can be exactly represented.
CAST and CONVERT:For a float or real expression, style can have one of the values shown in the following table. Other values are processed as 0.
Value
Output
0 (default)
A maximum of 6 digits. Use in scientific notation, when appropriate.
1
Always 8 digits. Always use in scientific notation.
2
Always 16 digits. Always use in scientific notation.
3
Always 17 digits. Use for lossless conversion. With this style, every distinct float or real value is guaranteed to convert to a distinct character string.
Applies to: SQL Server (Starting in SQL Server 2016 (13.x)) and Azure SQL Database.
126, 128, 129
Included for legacy reasons; a future release could deprecate these values.
You are using an implicit conversion from float to varchar(255), which implicitly uses style 0. Your floats all have more than six digits, so they are represented in scientific notation.
Floating point numbers are often shown in scientific notation. These types are used when range is more important than absolute precision. The numbers quickly become unwieldy in other formats. Scientific notation also helps to emphasise the limited precision.
You might like to use
STR or FORMAT instead:DECLARE @f float;
SET @f = 123456789012345e294;
SELECT
LTRIM(STR(@f, 309, 0)),
FORMAT(@f, 'F0');Both produce the output:
12345678901234500000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000
For float, integers from −253 to 253 (−9,007,199,254,740,992 to 9,007,199,254,740,992) can be exactly represented. For real, integers between −16777216 and 16777216 can be exactly represented.
Code Snippets
DECLARE @f float;
SET @f = 123456789012345e294;
SELECT
LTRIM(STR(@f, 309, 0)),
FORMAT(@f, 'F0');Context
StackExchange Database Administrators Q#294935, answer score: 8
Revisions (0)
No revisions yet.