返回顶部
首页 > 资讯 > 数据库 >Float与Real数据类型的陷阱
  • 785
分享到

Float与Real数据类型的陷阱

2024-04-02 19:04:59 785人浏览 泡泡鱼
摘要

sql Prompt根据数据库的对象名称、语法和代码片段自动进行检索,为用户提供合适的代码选择。自动脚本设置使代码简单易读--当开发者不大熟悉脚本时尤其有用。SQL Prompt安装即可使用,能大幅提高编码

sql Prompt根据数据库的对象名称、语法和代码片段自动进行检索,为用户提供合适的代码选择。自动脚本设置使代码简单易读--当开发者不大熟悉脚本时尤其有用。SQL Prompt安装即可使用,能大幅提高编码效率。本文介绍了使用Float或Real数据类型的危险。

浮点数据类型可容纳非常大的数字,但是缺少了精度。它们对于某些类型的科学计算很方便,但是在更广泛地使用时很危险,因为它们会引入较大的舍入误差。

浮点运算就是为了避免计算中的溢出错误而容忍和管理近似。在现实世界中,我们通常关心数字的准确性,而会牺牲空间和资源以避免溢出。

科学是在误差范围内工作的,而精确在商业会计中至关重要。当我还是一名初级程序员时,我曾经写过一种我认为是银行计算交易利润非常合适的方法。在一百万英镑中,最多也就一两便士的误差,我很满意。它使用了我们当时用来开发财务软件包的PL / 1编译器中固有的计算。我向他们展示了精心制作的应用程序,他们感到震惊。冷酷无情的银行家们毫不留情地表示一百万英镑没了几分钱。他们不会接受的。我被迫用精确的汇编代码编写一个精确的二进制编码的十进制(BCD)程序包。

SQL Prompt具有代码分析规则(BP023),该规则将提醒您使用Float或Real数据类型,这是因为它们可能会引入许多组织通常在其SQL Server数据上常规执行的那种计算方式。

Float与Real数据类型的陷阱

近似数的数据类型

浮点运算是在优先考虑节省内存的同时,提供了一种涉及大量运算的通用方法的时代设计出来的。尽管它对于许多类型的科学计算(尤其是那些符合浮点算术双精度IEEE 754标准的科学计算)仍然有用,但它必然是一种折衷方案。线索就是这种数据和算术的名称:“近似”。浮点数不能精确表示所有实数:此外,浮点运算不能精确表示所有算术运算。但是,即使不总是精确地保留数字,它们可以保留的数字的幅度范围也远大于其他数字类型。

使用浮点运算引起的问题是由于复杂计算过程中的四舍五入而引起的,如果数据处于“不良条件”状态,则最常见的问题就是输入中的细微变化会在输出中放大。随着数字表示精度的提高,这种不精确性已经不那么明显了,但是它们仍然存在。在使用有效但不能用浮点数表示的数字时,还存在一些深奥的限制,例如tan(π/ 2),但这些可能仅会激发数学家的兴趣。

SQL Server浮点数据类型

SQL标准具有三个浮点,近似数据类型、REAL、DOUBLE PRECISioN和FLOAT(n)。 SQL Server符合此要求,只是它没有DOUBLE PRECISION数据类型,而改用FLOAT(53)。 FLOAT(24)和FLOAT(53)数据类型对应于IEEE 754标准中的Binary32(Single)和Binary64(double),并分别存储在4和8字节中,并分别保留7和16位数字。当计算产生与使用还使用IEEE 754的.net框架的应用程序相同的结果很重要时,它们很有用。当数字的大小超过DECIMAL数据类型所允许的最大值(38位)时,还需要双精度类型,但精度下降。当然,近似数不能可靠地用于任何相等性检验中,例如WHERE子句。

使用REAL数据类型的计算(单精度)

我将尝试REAL数据类型。FLOAT(24)数据类型或更小的数据类型以相同的方式反应。在SQL Server中使用浮点数进行实验时,要记住的第一件事是,SSMS以掩盖微小差异的方式呈现浮点数。例如:

SELECT Convert(REAL,0.100000001490116119384765625)

…得到0.1

为了更准确地看到浮点数中存储了什么值,您必须使用STR()函数,指定实际需要的精度。

Float与Real数据类型的陷阱

Float与Real数据类型的陷阱

这已经令人担忧。毕竟,我们正在处理具有数百万行的数据,因此,除非像“银行家四舍五入”之类的结果取平均值,否则小错误就会堆积起来。这个错误已经接近我在引言中提到的“百万英镑的便士”(1/240000000)!

让我们避免使用0.1,并将其归结为奇怪的浮点数。1除以3怎么样?这肯定不是问题吧?

Float与Real数据类型的陷阱

哎呀,它错了。好的,这是一个很小的错误,但请记住我关于银行家的故事。答案是对还是错,穿着灰色西装的男人没有灰色阴影。在商学院,只有一个标记和一个叉。没有表示“足够近”的标志。

一个简单的测试是将数字1除以1到20。会出什么问题呢?

我们可以存储浮点数和数值计算的结果,将它们都转换为字符串,然后比较字符串(请注意,字符串STR()可以放在前导空格中,这会使情况变得复杂)。

Float与Real数据类型的陷阱

Float与Real数据类型的陷阱

现在,如果我们列出那些数字不匹配的行呢?

Float与Real数据类型的陷阱

Float与Real数据类型的陷阱

啊! 只有在除数为1、2、4、8或16的情况下,结果才正确。

如果您希望某种程度上的浮点数是准确的,而数值版本却不正确,则以下是在excel中计算出的数值商:

Float与Real数据类型的陷阱

使用FLOAT(25)或更高(双精度)的计算

如果使用双精度浮点数FLOAT(25)或更高的精度,则所有测试都将通过,因为STR()函数最多允许小数点右边16位。如果大于16,则结果将被截断。双精度数据类型具有16位数字,而单精度数据类型具有7位数字。您还将看到单精度数据类型正确获取了前七个数字。同样,双精度会正确获取前16位数字。我们可以扩大数字以查看近似值。

DECLARE @FirstApproximate FLOAT(53) = 10000000000000000.1
SELECT Str(@FirstApproximate,40,16) AS BigNumberWithaDecimal

Float与Real数据类型的陷阱

那小部分消失了,不是吗?这可能只是微小的差异,但是在某些计算中,它可能会引起问题。

结论

浮点算法在存储上既快速又经济,但提供了近似的结果。它适用于条件良好的科学应用,但不适用于财务计算,因为财务计算要求数字是“正确”或“错误”。它在数据库中还具有额外的缺点,因为您不能可靠且一致地测试两个近似数是否相等。

说永远不要在SQL数据类型或算术中使用浮点数是不正确的。在SQL标准中,有一个特定的近似类型。如今,在有适当要求的SQL Server中,我始终坚持使用双精度浮点数据类型。它们非常适合用于建模天气系统或绘制轨迹等目的,但不适用于普通组织可能使用数据库的计算类型。

如果发现错误使用了这些类型,则应改用合适的DECIMAL/ NUMERIC类型。如果您知道需要浮点算法并可以解释原因,那么您可能足够了解避免浮点的陷阱。

您可能感兴趣的文档:

--结束END--

本文标题: Float与Real数据类型的陷阱

本文链接: https://lsjlt.com/news/35260.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Float与Real数据类型的陷阱
    SQL Prompt根据数据库的对象名称、语法和代码片段自动进行检索,为用户提供合适的代码选择。自动脚本设置使代码简单易读--当开发者不大熟悉脚本时尤其有用。SQL Prompt安装即可使用,能大幅提高编码...
    99+
    2024-04-02
  • 使用Float或Real数据类型的危险
    SQL Prompt根据数据库的对象名称、语法和代码片段自动进行检索,为用户提供合适的代码选择。自动脚本设置使代码简单易读--当开发者不大熟悉脚本时尤其有用。SQL Prompt安装即可使用,能大幅提高编码效率。本文介绍了使用Float或R...
    99+
    2017-02-05
    使用Float或Real数据类型的危险
  • SQL中的real、float、decimal、numeric数据类型区别
    概述: 浮点数据类型包括real型、float型、decimal型和numeric型。浮点数据类型用于存储十进制小数。 在SQL Server 中浮点数值的数据采用上舍入(Round up)的方式进行存储,所谓上舍入也就是,要舍...
    99+
    2021-05-09
    SQL中的real float decimal numeric数据类型区别
  • JavaScript 数据类型指南:避免常见陷阱
    使用严格比较运算符 === 和 !==,避免 == 和 !=,它们允许类型转换。 布尔型值仅有 true 和 false 两种可能。 数字 区分整数和浮点数,整数不带小数点。 使用 Number() 函数将字符串转换为数字。 注意数...
    99+
    2024-04-02
  • MySQL中建表与常见的类型设计陷阱详解
    目录一、mysql建表语句二、MySQL建表字符串类型设计1、CHAR2、VARCHAR3、枚举类型设计实战三、MySQL建表ID和金额的设计与实战1、ID自增的设计2、互联网企业金额字段设计原理四、MySQL建表时间类...
    99+
    2024-04-02
  • Scala数据库开发时的陷阱
          今天在Scala数据库开发时遇到一个新建用户接口一直插入不了数据的情况,后来发现是我还没数据scala的play-slick框架导致的,其实类似于DataCloud...
    99+
    2024-04-02
  • NoSQL数据库的陷阱有哪些
    本篇内容介绍了“NoSQL数据库的陷阱有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Schema管理...
    99+
    2024-04-02
  • 【MySQL】MySQL建表与常见类型设计陷阱(MySQL专栏启动)
    📫作者简介:小明java问道之路,专注于研究 Java/ Liunx内核/ C++及汇编/计算机底层原理/源码,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性...
    99+
    2023-09-26
    mysql 数据库 java sql
  • 类与数据类型
    目录 类与数据类型 list.append()方法原理 端午节刚吃完粽子写下的这篇血泪文章!!! python3中统一了类与类型...
    99+
    2023-01-31
    数据类型
  • PHP和Apache服务器中的数组和数据类型:您需要避免的陷阱和错误。
    在PHP和Apache服务器中,数组和数据类型是最常见的操作。然而,许多PHP程序员在使用数组和数据类型时经常遇到陷阱和错误。在这篇文章中,我们将探讨一些您需要避免的陷阱和错误,以及如何避免它们。 数组越界 当您访问一个数组元素时,如...
    99+
    2023-09-15
    apache 数组 数据类型
  • MySQL数据库升级的一些"陷阱"
    对于商业数据库而言,数据库升级是一个优先级很高的事情,有版本升级路线图,有相应的补丁,而且对于方案还有一系列的演练,显然是一场硬仗。而在MySQL方向上,升级这件事情就被淡化了许多,好像只能证明它的存在而已,当然正是...
    99+
    2022-05-25
    MySQL 数据库升级
  • golang 函数调试与分析工具的陷阱与回避
    Go 函数调试与分析工具的陷阱与规避 在 Go 应用程序中进行调试和分析时,有许多有用的工具可供使用,例如:pprof、gotrace和go tool trace。然而,这些工具的使用...
    99+
    2024-05-06
    调试 golang
  • sqlite数据类型与c#数据类型对应表
    SQLite 数据类型C# 数据类型  BIGINT Int64   BIGUINT UInt64   BINARY Binary   BIT Boolean 首选 BLOB Binary 首选 BOOL Bool...
    99+
    2022-04-11
    sqlite数据类型与c#数据类型对应表
  • sqlite 的数据类型 与 pytho
    sqlite 数据类型 转载自:http://blog.csdn.net/zanfeng/article/details/17436381 一般数据采用的固定的静态数据类型,而SQLite采用的是动态数据类型,会根据存入值自动判断。SQ...
    99+
    2023-01-31
    数据类型 sqlite pytho
  • Java数据类型分类与基本数据类型转换
    目录1.数据类型的分类2.基本数据类型转换(1)自动类型转换(2)强制类型转换 1.数据类型的分类 Java的数据类型主要分为两类:基本数据类型、引用数据类型 Java中...
    99+
    2024-04-02
  • Windows数据类型与Go语言数据类型的异同点。
    Windows数据类型与Go语言数据类型的异同点 在计算机编程中,数据类型是非常重要的一个概念。不同的编程语言所支持的数据类型也不同。本文将重点探讨Windows数据类型和Go语言数据类型之间的异同点。 Windows数据类型 Window...
    99+
    2023-09-12
    windows 数据类型 关键字
  • java中如何使float类型数据保留两位小数
    方法1:用Math.round计算,这里返回的数字格式的float price=89.89; int itemNum=3; float totalPrice=price*itemNum; float num=(float)(Math.rou...
    99+
    2018-02-14
    java基础 java float 两位 小数
  • golang函数并发控制中常见的错误与陷阱
    并发错误和陷阱:错误1:データ競合:多个例程同时修改共享数据。错误2:デッドロック:两个以上例程互相等待,无限阻塞。错误3:チャネルの誤用:チャネルの早期クローズや、クローズしたチャネル...
    99+
    2024-04-24
    并发控制 陷阱 golang
  • 数据库日志中的陷阱:避免常见的错误
    错误配置日志级别 错误配置日志级别可导致日志记录不足或过度。选择适当的级别,例如: 调试:记录所有事件,包括调试信息。 信息:记录用户活动、性能指标等重要事件。 警告:记录潜在问题,例如索引使用情况低下。 错误:记录错误和异常。 未跟...
    99+
    2024-04-02
  • Java的数据类型与变量
    目录 🍊数据类型🍌整型🥝byte的范围 🍌浮点型🥝浮点数相关运算 🍊字符类型&#...
    99+
    2023-10-26
    1024程序员节 java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作