C/C++ long 数值溢出
在写 android NDK 的时候碰到的一个小情况
比如,我声明一个 native 方法:
public static native long foo();
然后,在实现里面这样写道:
当然,需要包含
sys/time.h
可是可是,收到的数是一个负数,我知道 long 默认是带符号的,可是如何跟 java 层转换呢?
java 可以轻松的使用
System.currentTimeMillis()
获取当前的毫秒时间戳,
C/C++ 要如何书写获取 ndk 返回无符号的大数呢?
摸摸你的胸
11 years, 11 months ago
Answers
Android平台是arm的cpu,目前都是32bit的。
而根据源码,timeval的tv_sec是long int,有符号32bit的。
106 #define __SLONGWORD_TYPE long int
"bits/types.h" line 69 of 200 --34%-- col 1
50 #define __TIME_T_TYPE __SLONGWORD_TYPE
"bits/typesizes.h" 66L, 2538C
152 __STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch. */
"bits/types.h" line 115 of 200 --57%-- col 18
67 /* A time value that is accurate to the nearest
68 microsecond but also has a range of years. */
69 struct timeval
70 {
71 __time_t tv_sec; /* Seconds. */
72 __suseconds_t tv_usec; /* Microseconds. */
"bits/time.h" 75L, 2552C
有符号32bit最大可以表示68年的秒数吧,从1970年算起的到现在的秒数是不会溢出的(还有20多年就溢出了)。
但如果转化为毫秒数扩大1000倍就必然会溢出。所以自1970年的毫秒数必须使用64bit来表示。
所以溢出发生在C代码return的时候,表达式val.tv_sec * 1000已经溢出了。
就这个问题而言,可以稍稍修改一下实现,让C返回一个结构体(成员是tv_sec和tv_usec)给java(应该可以吧?java我不是太熟悉)然后在java内转换为毫秒就可以了。
蓝天下的乌鸦
answered 11 years, 11 months ago