Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc318aee

Browse files
committed
Try to be more consistent about accepting denormalized float8 numbers.
On some platforms, strtod() reports ERANGE for a denormalized value (ie,one that can be represented as distinct from zero, but is too small to havefull precision). On others, it doesn't. It seems better to try to acceptthese values consistently, so add a test to see if the result valueindicates a true out-of-range condition. This should be okay per SingleUnix Spec. On machines where the underlying math isn't IEEE standard, thebehavior for such small numbers may not be very consistent, but then itwouldn't be anyway.Marti Raudsepp, after a proposal by Jeroen Vermeulen
1 parentb2e431a commitc318aee

File tree

1 file changed

+34
-10
lines changed

1 file changed

+34
-10
lines changed

‎src/backend/utils/adt/float.c

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ float4in(PG_FUNCTION_ARGS)
217217
/* did we not see anything that looks like a double? */
218218
if (endptr==num||errno!=0)
219219
{
220+
intsave_errno=errno;
221+
220222
/*
221223
* C99 requires that strtod() accept NaN and [-]Infinity, but not all
222224
* platforms support that yet (and some accept them but set ERANGE
@@ -237,11 +239,21 @@ float4in(PG_FUNCTION_ARGS)
237239
val=-get_float4_infinity();
238240
endptr=num+9;
239241
}
240-
elseif (errno==ERANGE)
241-
ereport(ERROR,
242-
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
243-
errmsg("\"%s\" is out of range for type real",
244-
orig_num)));
242+
elseif (save_errno==ERANGE)
243+
{
244+
/*
245+
* Some platforms return ERANGE for denormalized numbers (those
246+
* that are not zero, but are too close to zero to have full
247+
* precision). We'd prefer not to throw error for that, so try
248+
* to detect whether it's a "real" out-of-range condition by
249+
* checking to see if the result is zero or huge.
250+
*/
251+
if (val==0.0||val >=HUGE_VAL||val <=-HUGE_VAL)
252+
ereport(ERROR,
253+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
254+
errmsg("\"%s\" is out of range for type real",
255+
orig_num)));
256+
}
245257
else
246258
ereport(ERROR,
247259
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
@@ -410,6 +422,8 @@ float8in(PG_FUNCTION_ARGS)
410422
/* did we not see anything that looks like a double? */
411423
if (endptr==num||errno!=0)
412424
{
425+
intsave_errno=errno;
426+
413427
/*
414428
* C99 requires that strtod() accept NaN and [-]Infinity, but not all
415429
* platforms support that yet (and some accept them but set ERANGE
@@ -430,11 +444,21 @@ float8in(PG_FUNCTION_ARGS)
430444
val=-get_float8_infinity();
431445
endptr=num+9;
432446
}
433-
elseif (errno==ERANGE)
434-
ereport(ERROR,
435-
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
436-
errmsg("\"%s\" is out of range for type double precision",
437-
orig_num)));
447+
elseif (save_errno==ERANGE)
448+
{
449+
/*
450+
* Some platforms return ERANGE for denormalized numbers (those
451+
* that are not zero, but are too close to zero to have full
452+
* precision). We'd prefer not to throw error for that, so try
453+
* to detect whether it's a "real" out-of-range condition by
454+
* checking to see if the result is zero or huge.
455+
*/
456+
if (val==0.0||val >=HUGE_VAL||val <=-HUGE_VAL)
457+
ereport(ERROR,
458+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
459+
errmsg("\"%s\" is out of range for type double precision",
460+
orig_num)));
461+
}
438462
else
439463
ereport(ERROR,
440464
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp