天道酬勤,学无止境

使用Float或Real数据类型的危险

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

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

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

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

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

SQL Prompt使用教程:使用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()函数,指定实际需要的精度。


SQL Prompt使用教程:使用Float或Real数据类型的危险

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

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


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

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

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


SQL Prompt使用教程:使用Float或Real数据类型的危险

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


SQL Prompt使用教程:使用Float或Real数据类型的危险

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

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

SQL Prompt使用教程:使用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

SQL Prompt使用教程:使用Float或Real数据类型的危险

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

结论

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

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

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


受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Fortran 90种类参数(Fortran 90 kind parameter)
    问题 我在理解Fortran 90的kind参数时遇到麻烦。 据我所知,它不能确定变量的精度(即浮点数或双精度数),也不能确定变量的类型。 那么,它确定什么?它的作用到底是什么? 回答1 变量的KIND是一个整数标签,它告诉编译器应使用哪种支持的类型。 请注意,尽管KIND参数通常与该KIND变量中存储的字节数相同,但是Fortran标准并不需要。 也就是说,在很多系统上 REAl(KIND=4) :: xs ! 4 byte ieee float REAl(KIND=8) :: xd ! 8 byte ieee float REAl(KIND=16) :: xq ! 16 byte ieee float 但是可能有一些编译器,例如: REAL(KIND=1) :: XS ! 4 BYTE FLOAT REAL(KIND=2) :: XD ! 8 BYTE FLOAT REAL(KIND=3) :: XQ ! 16 BYTE FLOAT 对于整数和逻辑类型也是如此。 (如果我去挖掘,我大概可以找到例子。搜索对于新闻组comp.lang.fortran kind找到例子。Fortran语言的最明智的讨论出现在那里,与一些经验丰富的人做出贡献。) 因此,如果您不能指望在不同平台上为您提供相同数据表示的特定种类值,该怎么办? 这就是SELECTED_REAL_KIND和SELECTED
  • 如何将混合数据类型(int,float,char等)存储在数组中?(How can mixed data types (int, float, char, etc) be stored in an array?)
    问题 我想将混合数据类型存储在数组中。 怎么可以这样呢? 回答1 您可以使数组元素成为可区分的联合,也称为标记联合。 struct { enum { is_int, is_float, is_char } type; union { int ival; float fval; char cval; } val; } my_array[10]; type成员用于选择应为每个数组元素使用union的哪个成员。 因此,如果要将int存储在第一个元素中,则可以执行以下操作: my_array[0].type = is_int; my_array[0].val.ival = 3; 当您要访问数组的元素时,必须首先检查类型,然后使用联合的相应成员。 switch语句非常有用: switch (my_array[n].type) { case is_int: // Do stuff for integer, using my_array[n].ival break; case is_float: // Do stuff for float, using my_array[n].fval break; case is_char: // Do stuff for char, using my_array[n].cvar break; default: // Report an error, this
  • SQL Server中的数字,浮点数和小数之间的差异(Difference between numeric, float and decimal in SQL Server)
    问题 numeric , float和decimal数据类型之间有何区别?在哪种情况下应使用哪些区别? 对于任何形式的金融交易(例如,薪水领域),首选哪种交易,为什么? 回答1 仅当十进制(最多38位)提供的精度不足时才使用浮点或实数数据类型 近似数字数据类型不能存储为许多数字指定的确切值; 他们存储的值非常接近。(Technet) 避免在WHERE子句搜索条件中使用浮点或实数列,尤其是=和<>运算符(Technet) 因此通常来说,因为如果您的数字可以容纳,则十进制提供的精度为[10E38〜38位数],并且较小的Float存储空间(可能还有速度)并不重要,并且处理异常行为和近似数值类型的问题也不重要可以接受,一般使用Decimal 。 更有用的信息 数字=十进制(5到17个字节)(精确的数字数据类型) 将在.NET中映射为Decimal 在SQL Server中都具有(18,0)作为默认(precision,scale)参数 scale =可以存储在小数点右边的最大小数位数。 请注意,money(8字节)和smallmoney(4字节)也是精确的,并且映射到.NET中的Decimal并具有4个小数点(MSDN) 十进制和数字(Transact-SQL)-MSDN 实数(4字节)(近似数值数据类型) 将在.NET中映射为Single ISO的real同义词是float(24)
  • 如何防止在PHP中进行SQL注入?(How can I prevent SQL injection in PHP?)
    问题 这个问题的答案是社区的努力。 编辑现有答案以改善此职位。 它目前不接受新的答案或互动。 如果将用户输入未经修改地插入到SQL查询中,则该应用程序很容易受到SQL注入的影响,如以下示例所示: $unsafe_variable = $_POST['user_input']; mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')"); 这是因为用户可以输入类似value'); DROP TABLE table;-- value'); DROP TABLE table;-- ,查询变为: INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--') 可以采取什么措施来防止这种情况的发生? 回答1 使用准备好的语句和参数化查询。 这些是独立于任何参数发送到数据库服务器并由数据库服务器解析的SQL语句。 这样,攻击者就不可能注入恶意SQL。 您基本上有两种选择可以实现此目的: 使用PDO(对于任何受支持的数据库驱动程序): $stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name'); $stmt->execute([ 'name' => $name
  • Golang笔记之基本数据类型
    1、布尔类型布尔类型用于表示真假,类型名为bool,只有两个值true和false,占用一个字节宽度,零值为false var flag bool = true flag1 := false fmt.Println(flag,flag1)常用操作逻辑运算: 与(&&) 只有左、右表达式结果都为true,运算结果为truefmt.Println(flag&&true,flag1&&true) PS D:\goProject\day01> go run bool.go true false逻辑运算: 或(||) 只要左、右表达式有一个为true,运算结果为truefmt.Println(flag||true,flag1||true,flag1||false) PS D:\goProject\day01> go run bool.go true true false 逻辑运算: 非(!) 右表达式为true,运算结果为false;右表达式为false,运算结果为truefmt.Println(!flag,!flag1) PS D:\goProject\day01> go run bool.go false true关系运算 等于(==) 和不等于(!=)fmt.Println(flag == true, flag1 == true) PS D:\goProject\day01> go
  • 如何将字符串解析为float或int?(How do I parse a string to a float or int?)
    问题 在Python中,如何将"545.2222"类的数字字符串解析为其对应的浮点值545.2222 ? 或将字符串"31"解析为整数31 ? 我只是想知道如何解析浮str的float ,以及(分别)一个int str到int 。 回答1 >>> a = "545.2222" >>> float(a) 545.22220000000004 >>> int(float(a)) 545 回答2 def num(s): try: return int(s) except ValueError: return float(s) 回答3 检查字符串是否为浮点数的Python方法: def is_float(value): try: float(value) return True except: return False 此函数的更长更准确的名称可能是: is_convertible_to_float(value) 什么是Python中的浮点数,而不是浮点数,可能会让您感到惊讶: val is_float(val) Note -------------------- ---------- -------------------------------- "" False Blank string "127" True Passed string True True Pure sweet
  • htmlspecialchars和mysql_real_escape_string是否可以防止我的PHP代码被注入?(Do htmlspecialchars and mysql_real_escape_string keep my PHP code safe from injection?)
    问题 今天早些时候,有人问了有关Web应用程序中输入验证策略的问题。 在撰写本文时,最高答案是在PHP建议仅使用htmlspecialchars和mysql_real_escape_string 。 我的问题是:这是否总是足够? 还有更多我们应该知道的吗? 这些功能在哪里分解? 回答1 当涉及数据库查询时,请始终尝试使用准备好的参数化查询。 mysqli和PDO库支持此功能。 这比使用转义函数(例如mysql_real_escape_string绝对安全。 是的, mysql_real_escape_string实际上只是一个字符串转义函数。 这不是灵丹妙药。 它所要做的就是逃避危险字符,以便可以安全地在单个查询字符串中使用它们。 但是,如果您不事先清理输入内容,那么您将容易受到某些攻击媒介的攻击。 想象下面的SQL: $result = "SELECT fields FROM table WHERE id = ".mysql_real_escape_string($_POST['id']); 您应该能够看到这很容易被利用。 想象一下id参数包含公共攻击向量: 1 OR 1=1 那里没有危险的字符进行编码,因此它将直接通过转义过滤器。 离开我们: SELECT fields FROM table WHERE id= 1 OR 1=1 这是一个可爱的SQL注入向量
  • python 数据类型 之 数字类型
    数字类型 python数字类型有三种: 整数类型、浮点数类型、复数类型。 一、整数类型int() 十进制:1010 , 99 , -217 十六进制:0x9a , 0X89 ( 0x , 0X 开头表示十六进制) 二进制:0b010,-0B101 ( 0b , 0B 开头表示二进制 ) 八进制:0o123 , -0O456 ( 0o , 0O 开头是八进制 ) 二、浮点数类型float() 带有小数点和小数的数字python中的浮点数的数值范围和小数精度都存在限制,这种限制与在不同的计算机系统有关。 0.0 , -77. , -2.17 96e4 , 4.3e-3 , 9.6E5 ( 科学计数法 ) 科学计数法使用 ‘e’ 或 ‘E’ 作为幂的符号,以10为基数。 e a * 10 b(上标) 三、复数类型complex() z = a + bja 是实数部分, b 是虚数部分,a和b都是浮点类型,虚数部分用 j 或 J 表示。 12.6 + 5j -7.4 - 8.3j **对于复数 可以用 z.real来获得实部,z.imag来获得虚部 ** 四、数字类型的关系 1.三种数字类型存在一种逐渐“扩展”关系。 整数 -> 浮点数 -> 复数 2.不同数字类型之间可以进行混合运算,运算结果为最宽的类型 例如 : 124 + 4.0 = 127.0 (整数 + 浮点数 = 浮点数) 五
  • 在SQL Server中删除日期时间的时间部分的最佳方法(Best approach to remove time part of datetime in SQL Server)
    问题 从SQL Server的datetime字段中删除时间部分时,哪种方法提供最佳性能? a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0) 或者 b) select cast(convert(char(11), getdate(), 113) as datetime) 第二种方法的确以任何一种方式发送了更多的字节,但这可能不如转换速度那么重要。 两者看起来都非常快,但是处理成千上万行或更多行时速度可能会有所不同? 另外,是否有更好的方法可以消除SQL中日期时间的时间部分? 回答1 严格来说,方法a是最少的资源消耗: a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0) 事实证明,花了太多时间的人在相同的总持续时间(一百万行)中占用了太多CPU资源:SQL Server中从date + time获取日期的最有效方法? 我在其他地方也看到了类似的测试,结果也差不多。 我更喜欢DATEADD / DATEDIFF,因为: varchar受语言/日期格式问题的约束示例:为什么我的CASE表达式是不确定的? 浮动依赖于内部存储通过更改“ 0”基数,它可以扩展到每月的第一天,明天等 编辑,2011年10月 对于SQL Server 2008+,您可以CAST到date即CAST
  • 在SQL Server中从十进制中删除尾随零(Remove trailing zeros from decimal in SQL Server)
    问题 我有一列DECIMAL(9,6)即它支持999,123456之类的值。 但是当我插入123,4567之类的数据时,它变成123,456700 如何删除这些零? 回答1 decimal(9,6)在逗号右侧存储6位数字。 是否显示尾随零是格式决定,通常在客户端实施。 但是由于SSMS格式的float没有尾随零,因此您可以通过将decimal转换为float来删除尾随零: select cast(123.4567 as DECIMAL(9,6)) , cast(cast(123.4567 as DECIMAL(9,6)) as float) 印刷: 123.456700 123,4567 (我的小数点分隔符是逗号,但SSMS格式化带点的小数点。显然是已知问题。) 回答2 您可以使用FORMAT()函数(SqlAzure和Sql Server 2012+): SELECT FORMAT(CAST(15.12 AS DECIMAL(9,6)), 'g18') -- '15.12' SELECT FORMAT(CAST(0.0001575 AS DECIMAL(9,6)), 'g10') -- '0.000158' SELECT FORMAT(CAST(2.0 AS DECIMAL(9,6)), 'g15') -- '2' 与FLOAT(或REAL)一起使用时要小心:不要使用g17或更大
  • 如何防止PHP中的代码注入攻击?(How to prevent code injection attacks in PHP?)
    问题 我有点困惑,PHP中有很多函数,有些使用这个,有些使用那个。 有人使用: htmlspecialchars() , htmlentities() , strip_tags()等 哪个是正确的,你们通常使用什么? 这是正确的吗(如果有的话,建议我做一个更好的): $var = mysql_real_escape_string(htmlentities($_POST['username'])); 此行可以防止MySQL注入和XSS攻击?? 顺便说一句,除了XSS攻击和MySQL注入之外,还有其他需要注意的事情吗? 编辑 得出以下结论: 如果我想将字符串插入数据库,则无需使用htmlentities ,只需使用mysql_real_escape_string 。 显示数据时,请使用htmlentities() ,这是您的全部意思吗? 总结: 插入数据库时​​使用的mysql_real_escape_string htmlentities()数据输出到网页时使用的htmlentities() htmlspecialchars()何时使用? strip_tags()何时使用? 何时使用addslashes() ? 有人可以填写问号吗? 回答1 插入数据库时​​使用的mysql_real_escape_string htmlentities(
  • 如何在C ++中实现big int(How to implement big int in C++)
    问题 我想在C ++中实现一个大型int类作为编程练习,该类可以处理大于long int的数字。 我知道已经有几种开源实现,但是我想写自己的。 我正在尝试了解正确的方法是什么。 我知道一般的策略是将数字作为字符串获取,然后将其分解为较小的数字(例如,单个数字),然后将它们放置在数组中。 在这一点上,实现各种比较运算符应该相对简单。 我主要关心的是如何实现加法和乘法之类的东西。 我正在寻找一种通用的方法和建议,而不是实际的工作代码。 回答1 大int类要考虑的事项: 数学运算符:+,-,/,*,%不要忘记您的类可能在运算符的任一侧,可以将运算符链接起来,其中一个操作数可以是int,float,double等。 。 I / O运算符:>>,<<在此您可以了解如何根据用户输入正确创建类,以及如何格式化输出格式。 转换/转换:弄清楚您的大int类应转换为什么类型/类,以及如何正确处理转换。 快速列表将包括double和float,并可能包括int(使用适当的边界检查)和complex(假设它可以处理范围)。 回答2 一个有趣的挑战。 :) 我假设您想要任意长度的整数。 我建议采用以下方法: 考虑数据类型“ int”的二进制性质。 考虑使用简单的二进制运算来模拟CPU在添加东西时的电路功能。 如果您有更深入的兴趣,请考虑阅读有关半加法器和全加法器的Wikipedia文章。 您将执行类似的操作
  • C#等效于SQL Server数据类型(C# Equivalent of SQL Server DataTypes)
    问题 对于以下SQL Server数据类型,C#中对应的数据类型是什么? 精确数值 bigint numeric bit smallint decimal smallmoney int tinyint money 近似数值 float real 日期和时间 date datetimeoffset datetime2 smalldatetime datetime time 字串 char varchar text Unicode字符串 nchar nvarchar ntext 二进制字符串 binary varbinary image 其他数据类型 cursor timestamp hierarchyid uniqueidentifier sql_variant xml table (来源:MSDN) 回答1 这是针对SQL Server 2005的。表的更新版本适用于SQL Server 2008,SQL Server 2008 R2,SQL Server 2012和SQL Server 2014。 SQL Server数据类型及其.NET Framework等效项 下表列出了Microsoft SQL Server数据类型, System.Data.SqlTypes命名空间中SQL Server的公共语言运行时(CLR)中的等效项以及Microsoft .NET
  • 在MySQL数据库中存储经度/纬度时,理想的数据类型是什么?(What is the ideal data type to use when storing latitude / longitude in a MySQL database?)
    问题 请记住,我将在经纬度对上执行计算,哪种数据类型最适合与MySQL数据库一起使用? 回答1 在GIS中使用MySQL的空间扩展。 回答2 Google为使用Google Maps的示例“ Store Locator”应用程序提供了一个完成PHP / MySQL解决方案的起点。 在此示例中,他们将经度/经度值存储为“浮点数”,其长度为“ 10,6” http://code.google.com/apis/maps/articles/phpsqlsearch.html 回答3 基本上,这取决于您所需的位置精度。 使用DOUBLE,您将拥有3.5nm的精度。 DECIMAL(8,6)/(9,6)下降到16cm。 浮标为170万... 这个非常有趣的表具有更完整的列表:http://mysql.rjweb.org/doc.php/latlng: Datatype Bytes Resolution Deg*100 (SMALLINT) 4 1570 m 1.0 mi Cities DECIMAL(4,2)/(5,2) 5 1570 m 1.0 mi Cities SMALLINT scaled 4 682 m 0.4 mi Cities Deg*10000 (MEDIUMINT) 6 16 m 52 ft Houses/Businesses DECIMAL(6,4)/(7,4) 7 16
  • Mysql支持的数据类型(总结)
    一.数值类型Mysql支持所有标准SQL中的数值类型,其中包括严格数据类型(INTEGER,SMALLINT,DECIMAL,NUMBERIC),以及近似数值数据类型(FLOAT,REAL,DOUBLE PRESISION),并在此基础上进行扩展。扩展后增加了TINYINT,MEDIUMINT,BIGINT这3种长度不同的×××,并增加了BIT类型,用来存放位数据。整数类型 字节 范围(有符号) 范围(无符号) 用途 TINYINT 1字节 (-128,127) (0,255) 小整数值 SMALLINT 2字节 (-32 768,32 767) (0,65 535) 大整数值 MEDIUMINT 3字节 (-8 388 608,8 388 607) (0,16 777 215) 大整数值 INT或INTEGER 4字节 (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值 BIGINT 8字节 (-9 233 372 036 854 775 808,9 223 372 036 854 775 807) (0,18 446 744 073 709 551 615) 极大整数值 FLOAT 4字节 (-3.402 823 466 E+38,1.175 494 351 E-38),0,(1.175 494 351 E-38,3
  • 什么时候应该使用static_cast,dynamic_cast,const_cast和reinterpret_cast?(When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?)
    问题 的正确用法是: static_cast dynamic_cast const_cast reinterpret_cast C样式转换(type)value 函数样式转换type(value) 如何决定在特定情况下使用哪个? 回答1 static_cast是您应该尝试使用的第一个演员表。 它的作用类似于类型之间的隐式转换(例如, int到float或指向void*指针),并且它还可以调用显式转换函数(或隐式函数)。 在许多情况下,没有必要明确声明static_cast ,但必须注意, T(something)语法与(T)something等效,应避免使用(稍后会详细介绍)。 T(something, something_else)是安全的,并且保证可以调用构造函数。 static_cast也可以通过继承层次结构进行static_cast 。 向上(朝向基类)进行强制转换时不必要,但是向下进行转换(只要不通过virtual继承进行转换)就可以使用。 但是,它不会进行检查,并且将层次结构static_cast降低为实际上不是对象类型的类型是未定义的行为。 const_cast可用于将const删除或添加到变量; 没有其他C ++强制转换能够将其删除(甚至不能reinterpret_cast )。 重要的是要注意,仅当原始变量为const ,才可以修改以前的const值;
  • 什么是单态性限制?(What is the monomorphism restriction?)
    问题 我对haskell编译器有时会推断出比我所期望的少多态的类型感到困惑,例如在使用无点定义时。 看来问题出在“单态限制”,在较早版本的编译器上默认情况下处于启用状态。 考虑以下haskell程序: {-# LANGUAGE MonomorphismRestriction #-} import Data.List(sortBy) plus = (+) plus' x = (+ x) sort = sortBy compare main = do print $ plus' 1.0 2.0 print $ plus 1.0 2.0 print $ sort [3, 1, 2] 如果我用ghc编译,则不会得到错误,可执行文件的输出为: 3.0 3.0 [1,2,3] 如果我将main更改为: main = do print $ plus' 1.0 2.0 print $ plus (1 :: Int) 2 print $ sort [3, 1, 2] 我没有编译时错误,输出变为: 3.0 3 [1,2,3] 如预期的那样。 但是,如果我尝试将其更改为: main = do print $ plus' 1.0 2.0 print $ plus (1 :: Int) 2 print $ plus 1.0 2.0 print $ sort [3, 1, 2] 我收到类型错误: test
  • SQL之增删、注释
    因为同一SQL语句,不同厂商有不同的实现方式,因此同一SQL语句不一定在所有的数据库编辑器上能够正确运行,这里采用的是华为的openGauss。 一、数据库的创建、删除 1.创建数据库 CREATE DATABASE <db_name>; 2.删除数据库 DROP DATABASE <db_name>; 二、对表格的基本操作 一、表格的创建、删除 1.创建表格 CREATE TABLE <table_name> ( <list of elements> ); 2.删除表格 DROP TABLE <table_name>; 3.常用数据属性 整型:INT or INTERGER 实数型:REAL or FLOAT 字符型:CHAR(n) 固定n个长度的字符,即若实际长度小于n,则长度依然显示n 可变字符型:VARCHAR(n) 可变n个长度的字符,即若实际字符长度小于n,则显示为实际长度 使用示例: CREATE TABLE Sells ( bar CHAR(20) PRIMARY KEY, --设置为主键 beer VARCHAR(20) not null, --规定该属性不能为空 price REAL ); 如果需要定义联合主键,示例如下: CREATE TABLE Sells ( bar CHAR(20), beer VARCHAR(20), price REAL
  • 高性能MySQL —— 3、服务器性能剖析 和 Schema与数据类型优化
    高性能MySQL —— 3、服务器性能剖析 和 Schema与数据类型优化 1. 服务器性能剖析2. Schema与数据类型优化2.1 选择优化的数据类型2.1.1 整数类型2.1.2 实数类型2.1.3 字符串类型2.1.4 日期和时间类型2.1.5 位数据类型2.1.6 JSON2.1.7 地理空间数据Geometry 2.2 MySQL schema设计中的陷阱2.3 范式化和反范式化2.3.1 范式的优点和缺点2.3.2 反范式的优点和缺点2.3.3 混用范式化和反范式化2.3.4 缓存表和汇总表 2.4 加快Alter Table操作的速度2.4.1 只修改.frm文件2.4.2 快速创建索引 1. 服务器性能剖析 对于服务器性能剖析一章,因为我个人并非DBA方向而是后台开发方向,所以仅列出我觉得有用的内容。 慢查询问题定位方法: 开启慢查询日志,设置long_query_time来定义判断是否慢查询的阈值。通过分析慢查询日志,找到问题SQL;使用show status 或 show global status,不间断统计每个时间段中,各个MySQL计数点的数值,并绘制图形,定位问题点;使用MySQL 5.5之后的Performance Schema收集的数据库服务器性能参数进行判断。通过performance_schema设置开关;使用information
  • 什么是移动语义?(What is move semantics?)
    问题 我刚刚结束了对Scott Meyers进行的有关C ++ 0x的软件工程广播播客采访。 大多数新功能对我来说都是有意义的,除了一个功能,我现在对C ++ 0x感到非常兴奋。 我仍然没有动词的语义……到底是什么? 回答1 我发现用示例代码来理解移动语义是最容易的。 让我们从一个非常简单的字符串类开始,该类仅持有指向堆分配的内存块的指针: #include <cstring> #include <algorithm> class string { char* data; public: string(const char* p) { size_t size = std::strlen(p) + 1; data = new char[size]; std::memcpy(data, p, size); } 由于我们选择自己管理内存,因此我们需要遵循三个规则。 我将推迟编写赋值运算符,现在仅实现析构函数和复制构造函数: ~string() { delete[] data; } string(const string& that) { size_t size = std::strlen(that.data) + 1; data = new char[size]; std::memcpy(data, that.data, size); } 复制构造函数定义复制字符串对象的含义。