double转换long的疑问
在lua(5.1.4)下面测试的时候使用0x100000000的时候出现了问题,打印结果很明显,如下所示:
Lua 5.1. Copyright (C) - Lua.org, PUC-Rio
> print(0xffffffff) > print(0x100000000) > print(0x100000001)
一个同事给出了答复,但是说是强制转换的原因。不是太明白,按照long long转换成int的形式就是截断,就不会出现上面哪种都是4294967285的结果。5.1.4的源代码关于计算0xffffffff到整形的函数如下所示:
int luaO_str2d (const char *s, lua_Number *result) {
char *endptr;
*result = lua_str2number(s, &endptr);
if (endptr == s) return ; /* conversion failed */
if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
*result = cast_num(strtoul(s, &endptr, ));
if (*endptr == '\0') return ; /* most common case */
while (isspace(cast(unsigned char, *endptr))) endptr++;
if (*endptr != '\0') return ; /* invalid trailing characters? */
return ;
}
查看源代码可以知道cast_num就是转换成lua_number类型,也就是double类型。另外,直接写了一个简单的c++代码来看strtoul函数的结果,结果果真就是一样的,被截断了。代码如下(请跳过,放在这里自己记录一下):
void testStrtoul()
{
double a;
char pNum[] = "0x1100000000";
a = strtoul(pNum, , );
printf("%f, %f, %d\n", a, sizeof(double));
a += ;
unsigned long c = (unsigned long)pow(,) + ;
/*
()pow is double
()double --> unsigned long, the result is 0xffffffff
*/
double cc = pow(, ) * 4.0;
printf("cc = %f\n", cc);
c = cc;
printf("%f, %u\n", a, c);
}
因此,想去搜索一下strtoul函数的实现,看到一篇帖子[1].发现返回值是unsigned long,也因此猜想是double转换long的时候出现的问题,直接使用上面的例子就可以看到结果。一开始也是怀疑double强制转换成long并且溢出的时候,结果都是0xffffffff,和这位仁兄想的是一样的[2]。
但是,我非常不满意楼下给的回答:
(1)2楼给的上下界的溢出理论
(2)所谓的形象的比喻,水溢出杯子的理论
(3)double和long存储结构不一样
唯一有点含金量的是第三个回答,给不明白的人指出一条路去思考。起码去重现看一下这方面的知识点,其他的就不多说了,因为文章中用的java,而自己使用的是c++,所以不同之处就大敢多说了。因为从上面的解释来说,如果从截断角度分析都不行,4294967296即使是double的存储结构也不会有那么多bit位占1的,再怎么截断也不能够出现)XFFFFFFFF的情况。
对于自己碰到的问题,原因可以从下面这个帖子[4]看到:就是strtoul函数在溢出的时候就直接返回ULONG_MAX,而这个值也恰好就是(0xFFFFFFFF)
总结:
(1)对于自己的问题strtoul函数是自定义返回ULONG_MAX才会出现一直返回一个固定值的情况和[2]中的LZ遇到的情况很相近
(2)虽然说这些都是基本的计算机理论知识,但是还是要不断去探究其中的细节
(3)对于java的那种情况,是不是强制转换中作了什么处理不发表评论了,没有发言权
(4)c++中的double直接转换成long类型还是截断处理的,比如4294967296前置转化成long类型就是0,4294967295*2转换之后的结果为4294967294
参考:
[1]http://blog.csdn.net/czxyhll/article/details/7876084
[2]http://bbs.csdn.net/topics/330076483
[3]http://www.cnblogs.com/fly-height/articles/2340396.html
[4]http://www.cplusplus.com/reference/cstdlib/strtoul/
double转换long的疑问的更多相关文章
- 关于c中 int, float, double转换中存在的精度损失问题
先看一段代码实验: #include<limits> #include<iostream> using namespace std; int main() { unsigned ...
- Java中float和double转换的问题
为什么double转float不会出现数据误差,而float转double却误差如此之大? double d = 3.14; float f = (float)d; System.out.prin ...
- java.math.BigDecimal转换double double转换java.math.BigDecimal
有方法 java.math.BigDecimal.doubleValue() BigDecimal a = new BigDecimal(1000);return a.doubleValue(); p ...
- float(double)快速转换int的方法
自己写一个软件渲染器的时候,无意中发现float转换int非常耗时,于是查阅文章,这才有了这个命题,以前不清楚还有这么个机制.网上看了很多文章,搜索到了一个数字6755399441055744,这个是 ...
- 基于Visual C++2013拆解世界五百强面试题--题4-double转换成字符串
请用C语言实现将double类型数据转换成字符串,再转换成double类型的数据.int类型的数据 想要完成题目中的功能,首先我们的先对系统存储double的格式有所了解. 浮点数编码转换使用的是IE ...
- C++有符号和无符号数的转换
本文转自:http://www.94cto.com/index/Article/content/id/59973.html 1.引例: 今天在做了一道关于有符号数和无符号数相互转换及其左移/右移的问题 ...
- 关于有符号数和无符号数的转换 - C/C++
转载自:http://www.94cto.com/index/Article/content/id/59973.html 1.引例: 今天在做了一道关于有符号数和无符号数相互转换及其左移/右移的问题, ...
- 黑马程序员-c语言-类型强制转换
强制转换的条件: 1.当所声明的类型不能满足所符值的变量时,需要转换声明的类型,以便能够存储变量. 例如:short存储的最大值为32767,但是所要符值大于32767时,short类型不符合,需要转 ...
- java基本数据类型及相互间的转换
1.首先复习一下java的基本数据类型,见下图 2.比较他们的字节数 备注:1字节(Byte)=8位(Bit) 3.转换中的知识点 *java中整数类型默认的int类型:小数类型默认的double: ...
随机推荐
- sql server 保留小数,向上保留指定位数的小数,仅记录,勿看。
比如 4.05 要取成 4.1 , 4.16 取成 4.2 ,4.5 取成 4.5 ,意思就是小数部分第二位不管是多少都丢掉然后加0.1,但是如果是 4.5 这样完整的就不需要处理. 可以像下面这么写 ...
- (转)Uri详解之——Uri结构与代码提取
前言:依然没有前言…… 相关博客:1.<Uri详解之——Uri结构与代码提取>2.<Uri详解之二——通过自定义Uri外部启动APP与Notification启动> 上几篇给大 ...
- (转)用mysql自带工具mysqlslap对数据库进行压力测试
http://aolens.blog.51cto.com/7021142/1901557-------用mysql自带工具mysqlslap对数据库进行压力测试 mysqlslap是mysql自带的工 ...
- vue中的坑 --- 锚点与查询字符串
在vue中,由于是单页面SPA,所以需要使用锚点来定位,在vue的官方文档中提到过也可以不使用锚点的情况,就是在vue-router中使用history模式,这样,在url中就不会出现丑陋的#了,但是 ...
- LinuxShell脚本基础 6-case...esac的使用和通配符
1.case...esac的使用 #!/bin/bash echo "请输入编号 选择不同的显示文件和目录方式:" echo "1 - 普通显示" echo & ...
- 机器学习——LightGBM
基础概念 LigthGBM是boosting集合模型中的新进成员,它和xgboost一样是对GBDT的高效实现,很多方面会比xgboost表现的更为优秀.原理上它和GBDT及xgboot类似,都采用损 ...
- 【c++】流状态的查询和控制
源自 c++primer 4th, 248页 代码 #include <iostream> #include <limits> #include <stdexcept&g ...
- NOI 2018 酱油记
转眼离 NOI 2018 已经过了一个星期了,退役的我还是随便来水水吧. 语法.错字之类的可能会很多,但是我也不拘这点小节了. 恭喜 yww, zjt, sk 进队,zwl, myh au , yay ...
- Magento 2开发教程 - 如何添加新产品属性
添加产品属性是一种在Magento 1 和 Magento 2最受欢迎的业务. 属性是解决许多与产品相关的实际任务的有力方法. 这是一个相当广泛的话题,但在这个视频中,我们将讨论添加一个下拉类型属性到 ...
- [转]JavaScript和html5 canvas生成圆形印章
本文转自:http://www.cnblogs.com/dragondean/p/6013529.html 代码: function createSeal(id,company,name){ var ...