C++学习之Numeric overflow due to incorrect type casting

由于不正确的类型转换导致的数字溢出,可能会导致错误的结果。这种错误通过debug并不好追踪。

示例1:


typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
uint64_t foo(uint32_t x, uint32_t y){
    uint64_t z;
    z = (uint64_t)( x * y );
    z = (uint64_t)( y * 100000U);
    return z;
}

上面的代码中,开发者希望两数相乘的结果占 64 字节,尽管 x 和 y 都是32位的。但如果 x * y 所得结果大于 32 位,再进行强制类型转换就会出现溢出问题。上面的 5/6 两行 code 都会产生 klockwork issue。


fixed code example 1


typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
uint64_t foo(uint32_t x, uint32_t y){
    uint64_t z;
    z = (uint64_t)( x ) * y;
    z = (uint64_t)( y ) * 100000U;
    return z;
}

第 5 行中先将 x 强制转换为 64 位,然后在与 y 相乘时,y 会先自动转换为 64 位的数字,之后两者相乘即可得一个 64 位数字 z 。第 6 行同理。

示例 2:


typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
uint32_t get_val();
uint64_t foo(uint32_t x, uint32_t y){
    uint64_t z;
    z = (uint64_t)( y * get_val() );
    return z;
}

fixed code example 2:


typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
uint32_t get_val();
uint64_t foo(uint32_t x, uint32_t y){
    uint64_t z;
    z = (uint64_t)( y ) * get_val();
    return z;
}
### 解决SQL Server中将VARCHAR类型数据转换为NUMERIC类型的错误 当尝试将在`VARCHAR`或`NVARCHAR`列中的字符数据转换为数值型(`NUMERIC`)时,如果存在无法解析成有效数字的字符,则会引发异常。为了安全地执行这样的转换操作并处理可能发生的错误情况,在T-SQL中有几种方法可以采用。 #### 使用TRY_CONVERT() 函数 对于SQL Server版本支持的情况(2012及以上),推荐使用`TRY_CONVERT()`来代替直接调用`CONVERT()`或`CAST()`。该函数会在遇到非法输入时不抛出错误而是返回NULL值[^1]: ```sql SELECT CASE WHEN TRY_CONVERT(NUMERIC(18, 4), YourVarcharColumn) IS NOT NULL THEN CONVERT(NUMERIC(18, 4), YourVarcharColumn) ELSE 0 END AS ConvertedValue FROM YourTable; ``` 这里假设目标精度为18位整数部分加上四位小数部分;实际应用中应根据业务需求调整这些参数设置。 #### 应用ISNUMERIC() 另一种方式是在进行显式的类型转换之前先通过内置函数`ISNUMERIC()`测试待转字符串是否符合预期格式。需要注意的是此方法并非完全可靠因为某些特殊符号也会被认为是合法的数字组成部分[^2]: ```sql SELECT * FROM ( SELECT *, CASE WHEN ISNUMERIC(NationalIDNumber)=1 AND NationalIDNumber NOT LIKE '%[^0-9]%'THEN CAST(NationalIDNumber AS NUMERIC(18)) ELSE NULL END AS NumericId FROM HumanResources.Employee ) t WHERE NumericId IS NOT NULL; ``` 上述查询片段展示了如何过滤掉那些包含非数字字符的身份号码记录,并只保留能够成功转变为`NUMERIC`类型的条目。 #### 数据清理与验证 除了编程层面的技术手段外,还应该考虑从业务逻辑角度出发做好前端输入控制以及定期批量校验数据库内存量数据的质量工作,从而减少因脏数据而导致运行期报错的可能性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值