nan.test 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. # 2008 April 28
  2. #
  3. # The author disclaims copyright to this source code. In place of
  4. # a legal notice, here is a blessing:
  5. #
  6. # May you do good and not evil.
  7. # May you find forgiveness for yourself and forgive others.
  8. # May you share freely, never taking more than you give.
  9. #
  10. #***********************************************************************
  11. #
  12. # Ticket #3060
  13. #
  14. # Make sure IEEE floating point NaN values are handled properly.
  15. # SQLite should always convert NaN into NULL.
  16. #
  17. # Also verify that the decimal to IEEE754 binary conversion routines
  18. # correctly generate 0.0, +Inf, and -Inf as appropriate for numbers
  19. # out of range.
  20. #
  21. # $Id: nan.test,v 1.5 2008/09/18 11:30:13 danielk1977 Exp $
  22. #
  23. set testdir [file dirname $argv0]
  24. source $testdir/tester.tcl
  25. # Do not use a codec for tests in this file, as the database file is
  26. # manipulated directly using tcl scripts (using the [hexio_write] command).
  27. #
  28. do_not_use_codec
  29. do_test nan-1.1.1 {
  30. db eval {
  31. PRAGMA auto_vacuum=OFF;
  32. PRAGMA page_size=1024;
  33. CREATE TABLE t1(x FLOAT);
  34. }
  35. set ::STMT [sqlite3_prepare db "INSERT INTO t1 VALUES(?)" -1 TAIL]
  36. sqlite3_bind_double $::STMT 1 NaN
  37. sqlite3_step $::STMT
  38. sqlite3_reset $::STMT
  39. db eval {SELECT x, typeof(x) FROM t1}
  40. } {{} null}
  41. if {$tcl_platform(platform) != "symbian"} {
  42. do_realnum_test nan-1.1.2 {
  43. sqlite3_bind_double $::STMT 1 +Inf
  44. sqlite3_step $::STMT
  45. sqlite3_reset $::STMT
  46. db eval {SELECT x, typeof(x) FROM t1}
  47. } {{} null inf real}
  48. do_realnum_test nan-1.1.3 {
  49. sqlite3_bind_double $::STMT 1 -Inf
  50. sqlite3_step $::STMT
  51. sqlite3_reset $::STMT
  52. db eval {SELECT x, typeof(x) FROM t1}
  53. } {{} null inf real -inf real}
  54. do_realnum_test nan-1.1.4 {
  55. sqlite3_bind_double $::STMT 1 -NaN
  56. sqlite3_step $::STMT
  57. sqlite3_reset $::STMT
  58. db eval {SELECT x, typeof(x) FROM t1}
  59. } {{} null inf real -inf real {} null}
  60. do_realnum_test nan-1.1.5 {
  61. sqlite3_bind_double $::STMT 1 NaN0
  62. sqlite3_step $::STMT
  63. sqlite3_reset $::STMT
  64. db eval {SELECT x, typeof(x) FROM t1}
  65. } {{} null inf real -inf real {} null {} null}
  66. do_realnum_test nan-1.1.6 {
  67. sqlite3_bind_double $::STMT 1 -NaN0
  68. sqlite3_step $::STMT
  69. sqlite3_reset $::STMT
  70. db eval {SELECT x, typeof(x) FROM t1}
  71. } {{} null inf real -inf real {} null {} null {} null}
  72. do_test nan-1.1.7 {
  73. db eval {
  74. UPDATE t1 SET x=x-x;
  75. SELECT x, typeof(x) FROM t1;
  76. }
  77. } {{} null {} null {} null {} null {} null {} null}
  78. }
  79. # The following block of tests, nan-1.2.*, are the same as the nan-1.1.*
  80. # tests above, except that the SELECT queries used to validate data
  81. # convert floating point values to text internally before returning them
  82. # to Tcl. This allows the tests to be run on platforms where Tcl has
  83. # problems converting "inf" and "-inf" from floating point to text format.
  84. # It also tests the internal float->text conversion routines a bit.
  85. #
  86. do_test nan-1.2.1 {
  87. db eval {
  88. DELETE FROM T1;
  89. }
  90. sqlite3_bind_double $::STMT 1 NaN
  91. sqlite3_step $::STMT
  92. sqlite3_reset $::STMT
  93. db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
  94. } {{} null}
  95. do_test nan-1.2.2 {
  96. sqlite3_bind_double $::STMT 1 +Inf
  97. sqlite3_step $::STMT
  98. sqlite3_reset $::STMT
  99. db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
  100. } {{} null Inf real}
  101. do_test nan-1.2.3 {
  102. sqlite3_bind_double $::STMT 1 -Inf
  103. sqlite3_step $::STMT
  104. sqlite3_reset $::STMT
  105. db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
  106. } {{} null Inf real -Inf real}
  107. do_test nan-1.2.4 {
  108. sqlite3_bind_double $::STMT 1 -NaN
  109. sqlite3_step $::STMT
  110. sqlite3_reset $::STMT
  111. db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
  112. } {{} null Inf real -Inf real {} null}
  113. do_test nan-1.2.5 {
  114. sqlite3_bind_double $::STMT 1 NaN0
  115. sqlite3_step $::STMT
  116. sqlite3_reset $::STMT
  117. db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
  118. } {{} null Inf real -Inf real {} null {} null}
  119. do_test nan-1.2.6 {
  120. sqlite3_bind_double $::STMT 1 -NaN0
  121. sqlite3_step $::STMT
  122. sqlite3_reset $::STMT
  123. db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
  124. } {{} null Inf real -Inf real {} null {} null {} null}
  125. do_test nan-1.2.7 {
  126. db eval {
  127. UPDATE t1 SET x=x-x;
  128. SELECT CAST(x AS text), typeof(x) FROM t1;
  129. }
  130. } {{} null {} null {} null {} null {} null {} null}
  131. do_test nan-2.1 {
  132. db eval {
  133. DELETE FROM T1;
  134. }
  135. sqlite3_bind_double $::STMT 1 NaN
  136. sqlite3_step $::STMT
  137. sqlite3_reset $::STMT
  138. db eval {SELECT x, typeof(x) FROM t1}
  139. } {{} null}
  140. sqlite3_finalize $::STMT
  141. # SQLite always converts NaN into NULL so it is not possible to write
  142. # a NaN value into the database file using SQLite. The following series
  143. # of tests writes a normal floating point value (0.5) into the database,
  144. # then writes directly into the database file to change the 0.5 into NaN.
  145. # Then it reads the value of the database to verify it is converted into
  146. # NULL.
  147. #
  148. do_test nan-3.1 {
  149. db eval {
  150. DELETE FROM t1;
  151. INSERT INTO t1 VALUES(0.5);
  152. PRAGMA auto_vacuum=OFF;
  153. PRAGMA page_size=1024;
  154. VACUUM;
  155. }
  156. hexio_read test.db 2040 8
  157. } {3FE0000000000000}
  158. do_test nan-3.2 {
  159. db eval {
  160. SELECT x, typeof(x) FROM t1
  161. }
  162. } {0.5 real}
  163. do_test nan-3.3 {
  164. db close
  165. hexio_write test.db 2040 FFF8000000000000
  166. sqlite3 db test.db
  167. db eval {SELECT x, typeof(x) FROM t1}
  168. } {{} null}
  169. do_test nan-3.4 {
  170. db close
  171. hexio_write test.db 2040 7FF8000000000000
  172. sqlite3 db test.db
  173. db eval {SELECT x, typeof(x) FROM t1}
  174. } {{} null}
  175. do_test nan-3.5 {
  176. db close
  177. hexio_write test.db 2040 FFFFFFFFFFFFFFFF
  178. sqlite3 db test.db
  179. db eval {SELECT x, typeof(x) FROM t1}
  180. } {{} null}
  181. do_test nan-3.6 {
  182. db close
  183. hexio_write test.db 2040 7FFFFFFFFFFFFFFF
  184. sqlite3 db test.db
  185. db eval {SELECT x, typeof(x) FROM t1}
  186. } {{} null}
  187. # Verify that the sqlite3AtoF routine is able to handle extreme
  188. # numbers.
  189. #
  190. do_test nan-4.1 {
  191. db eval {DELETE FROM t1}
  192. db eval "INSERT INTO t1 VALUES([string repeat 9 307].0)"
  193. db eval {SELECT x, typeof(x) FROM t1}
  194. } {1e+307 real}
  195. do_test nan-4.2 {
  196. db eval {DELETE FROM t1}
  197. db eval "INSERT INTO t1 VALUES([string repeat 9 308].0)"
  198. db eval {SELECT x, typeof(x) FROM t1}
  199. } {1e+308 real}
  200. do_test nan-4.3 {
  201. db eval {DELETE FROM t1}
  202. db eval "INSERT INTO t1 VALUES(-[string repeat 9 307].0)"
  203. db eval {SELECT x, typeof(x) FROM t1}
  204. } {-1e+307 real}
  205. do_test nan-4.4 {
  206. db eval {DELETE FROM t1}
  207. db eval "INSERT INTO t1 VALUES(-[string repeat 9 308].0)"
  208. db eval {SELECT x, typeof(x) FROM t1}
  209. } {-1e+308 real}
  210. do_test nan-4.5 {
  211. db eval {DELETE FROM t1}
  212. set big -[string repeat 0 10000][string repeat 9 308].[string repeat 0 10000]
  213. db eval "INSERT INTO t1 VALUES($big)"
  214. db eval {SELECT x, typeof(x) FROM t1}
  215. } {-1e+308 real}
  216. do_test nan-4.6 {
  217. db eval {DELETE FROM t1}
  218. set big [string repeat 0 10000][string repeat 9 308].[string repeat 0 10000]
  219. db eval "INSERT INTO t1 VALUES($big)"
  220. db eval {SELECT x, typeof(x) FROM t1}
  221. } {1e+308 real}
  222. if {$tcl_platform(platform) != "symbian"} {
  223. # Do not run these tests on Symbian, as the Tcl port doesn't like to
  224. # convert from floating point value "-inf" to a string.
  225. #
  226. do_realnum_test nan-4.7 {
  227. db eval {DELETE FROM t1}
  228. db eval "INSERT INTO t1 VALUES([string repeat 9 309].0)"
  229. db eval {SELECT x, typeof(x) FROM t1}
  230. } {inf real}
  231. do_realnum_test nan-4.8 {
  232. db eval {DELETE FROM t1}
  233. db eval "INSERT INTO t1 VALUES(-[string repeat 9 309].0)"
  234. db eval {SELECT x, typeof(x) FROM t1}
  235. } {-inf real}
  236. }
  237. do_test nan-4.9 {
  238. db eval {DELETE FROM t1}
  239. db eval "INSERT INTO t1 VALUES([string repeat 9 309].0)"
  240. db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
  241. } {Inf real}
  242. do_test nan-4.10 {
  243. db eval {DELETE FROM t1}
  244. db eval "INSERT INTO t1 VALUES(-[string repeat 9 309].0)"
  245. db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
  246. } {-Inf real}
  247. do_test nan-4.11 {
  248. db eval {DELETE FROM t1}
  249. db eval "INSERT INTO t1 VALUES(1234.5[string repeat 0 10000]12345)"
  250. db eval {SELECT x, typeof(x) FROM t1}
  251. } {1234.5 real}
  252. do_test nan-4.12 {
  253. db eval {DELETE FROM t1}
  254. db eval "INSERT INTO t1 VALUES(-1234.5[string repeat 0 10000]12345)"
  255. db eval {SELECT x, typeof(x) FROM t1}
  256. } {-1234.5 real}
  257. do_test nan-4.13 {
  258. db eval {DELETE FROM t1}
  259. set small [string repeat 0 10000].[string repeat 0 324][string repeat 9 10000]
  260. db eval "INSERT INTO t1 VALUES($small)"
  261. db eval {SELECT x, typeof(x) FROM t1}
  262. } {0.0 real}
  263. do_test nan-4.14 {
  264. db eval {DELETE FROM t1}
  265. set small \
  266. -[string repeat 0 10000].[string repeat 0 324][string repeat 9 10000]
  267. db eval "INSERT INTO t1 VALUES($small)"
  268. db eval {SELECT x, typeof(x) FROM t1}
  269. } {0.0 real}
  270. # These tests test some really, really small floating point numbers.
  271. #
  272. if {$tcl_platform(platform) != "symbian"} {
  273. # These two are not run on symbian because tcl has trouble converting
  274. # the very small numbers back to text form (probably due to a difference
  275. # in the sprintf() implementation).
  276. #
  277. do_test nan-4.15 {
  278. db eval {DELETE FROM t1}
  279. set small \
  280. [string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
  281. db eval "INSERT INTO t1 VALUES($small)"
  282. db eval {SELECT x, typeof(x) FROM t1}
  283. } {9.88131291682493e-324 real}
  284. do_test nan-4.16 {
  285. db eval {DELETE FROM t1}
  286. set small \
  287. -[string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
  288. db eval "INSERT INTO t1 VALUES($small)"
  289. db eval {SELECT x, typeof(x) FROM t1}
  290. } {-9.88131291682493e-324 real}
  291. }
  292. do_test nan-4.17 {
  293. db eval {DELETE FROM t1}
  294. set small [string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
  295. db eval "INSERT INTO t1 VALUES($small)"
  296. db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
  297. } {9.88131291682493e-324 real}
  298. do_test nan-4.18 {
  299. db eval {DELETE FROM t1}
  300. set small \
  301. -[string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
  302. db eval "INSERT INTO t1 VALUES($small)"
  303. db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
  304. } {-9.88131291682493e-324 real}
  305. do_realnum_test nan-4.20 {
  306. db eval {DELETE FROM t1}
  307. set big [string repeat 9 10000].0e-9000
  308. db eval "INSERT INTO t1 VALUES($big)"
  309. db eval {SELECT x, typeof(x) FROM t1}
  310. } {inf real}
  311. do_realnum_test nan-4.30 {
  312. db eval {
  313. DELETE FROM t1;
  314. INSERT INTO t1 VALUES('2.5e+9999');
  315. SELECT x, typeof(x) FROM t1;
  316. }
  317. } {inf real}
  318. do_realnum_test nan-4.31 {
  319. db eval {
  320. DELETE FROM t1;
  321. INSERT INTO t1 VALUES('2.5e+10000');
  322. SELECT x, typeof(x) FROM t1;
  323. }
  324. } {inf real}
  325. do_realnum_test nan-4.32 {
  326. db eval {
  327. DELETE FROM t1;
  328. INSERT INTO t1 VALUES('2.5e-9999');
  329. SELECT x, typeof(x) FROM t1;
  330. }
  331. } {0.0 real}
  332. do_realnum_test nan-4.33 {
  333. db eval {
  334. DELETE FROM t1;
  335. INSERT INTO t1 VALUES('2.5e-10000');
  336. SELECT x, typeof(x) FROM t1;
  337. }
  338. } {0.0 real}
  339. do_realnum_test nan-4.34 {
  340. db eval {
  341. DELETE FROM t1;
  342. INSERT INTO t1 VALUES('2.5e2147483650');
  343. SELECT x, typeof(x) FROM t1;
  344. }
  345. } {inf real}
  346. do_realnum_test nan-4.35 {
  347. db eval {
  348. DELETE FROM t1;
  349. INSERT INTO t1 VALUES('2.5e-2147483650');
  350. SELECT x, typeof(x) FROM t1;
  351. }
  352. } {0.0 real}
  353. finish_test