趣味思考题

我看你有戏 2009-12-28 10:16:01
declare @StartIP int
set @StartIP=(0x7FFFFFFF+1)
print @StartIP

这段代码执行提示溢出

消息 8115,级别 16,状态 2,第 3 行
将 expression 转换为数据类型 int 时出现算术溢出错误。


declare @StartIP bigint
set @StartIP=(0x7FFFFFFFFFFFFFFF+1)
print @StartIP

为啥下面这段就不提示溢出呢?
...全文
133 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
playwarcraft 2009-12-28
  • 打赏
  • 举报
回复
这其实涉及到的是 sql数据类型的优先级问题

declare @StartIP int
set @StartIP=(0x7FFFFFFF+1)
print @StartIP

declare @StartIP bigint
set @StartIP=(0x7FFFFFFFFFFFFFFF+1)
print @StartIP

其关键是在 这个 1 上,sql 默认其是 int 型!
所以两者相加,0x7FFFFFFF 和 0x7FFFFFFFFFFFFFFF 都 被默认转换成 int型

select convert(int,0x7FFFFFFF)
/*2147483647*/
select convert(int,0x7FFFFFFFFFFFFFFF)
/*-1*/

前者+1后,超出Int的范围
后者+1后,=0,不用Bigint都可以, 甚至你定义成smallint都可以。

当然,再看一下,如果你把后者改一下
declare @StartIP bigint
set @StartIP=(0x7FFFFFFFFFFFFFFF+convert(bigint,1))
print @StartIP

那么同样是会报溢出的错误的。。。

同样,如果把前者的+1指定为smallint,也就不会报错了
declare @StartIP int
set @StartIP=(0x7FFFFFFF+convert(smallint,1))
print @StartIP

/* 0 */
liyangfd 2009-12-28
  • 打赏
  • 举报
回复
学习了
SQL77 2009-12-28
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 henry3695 的回复:]
引用 14 楼 colacat911 的回复:
看来我理解有误,的确0x7FFFFFFFFFFFFFFF是bigint的最大值

而SQL是转成int的-1然后+1变成0在转成bigint的,你可以看下@StartIP结果是0


好像是这么个道理,呵呵,学习了
[/Quote]
..
我看你有戏 2009-12-28
  • 打赏
  • 举报
回复
OK GOOD
忆轩辕 2009-12-28
  • 打赏
  • 举报
回复
具体来说还是二进制转的时候出问题了,具体转成什么,转了几次要问微软

所以还是需要显式转换



select cast(0x7FFFFFFFFFFFFFFF as bigint)+1


--------------------
消息 8115,级别 16,状态 2,第 1 行
将 expression 转换为数据类型 bigint 时发生算术溢出错误。

(1 行受影响)


我看你有戏 2009-12-28
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 colacat911 的回复:]
看来我理解有误,的确0x7FFFFFFFFFFFFFFF是bigint的最大值

而SQL是转成int的-1然后+1变成0在转成bigint的,你可以看下@StartIP结果是0
[/Quote]

好像是这么个道理,呵呵,学习了
忆轩辕 2009-12-28
  • 打赏
  • 举报
回复
看来我理解有误,的确0x7FFFFFFFFFFFFFFF是bigint的最大值

而SQL是转成int的-1然后+1变成0在转成bigint的,你可以看下@StartIP结果是0
忆轩辕 2009-12-28
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 henry3695 的回复:]
引用 10 楼 colacat911 的回复:
ulong类型
0~18 446,744,073,709,551,615


bigint
-2^63 (-9,223,372,036,854,775,808) 至 2^63-1 (9,223,372,036,854,775,807)

int
-2^31 (-2,147,483,648) 到2^31 - 1 (2,147,483,647)

SQL codeSELECTCONVERT(INT,0x7FFFFFFF),CONVERT(INT,0x7FFFFFFFFFFFFFFF)----------- -----------2147483647-1

(1 行受影响)

至于ulong ee = 0x7FFFFFFFFFFFFFFF+1会报溢出应该是由于0x7FFFFFFFFFFFFFFF是-1的原因




那为啥 sql语句 bigint的时候不会报错呢,
declare @StartIP bigint
set @StartIP=(0x7FFFFFFFFFFFFFFF+1)


@StartIP的值就直接为0了


[/Quote]

ulong类型不支持负值,而bigint支持
Garnett_KG 2009-12-28
  • 打赏
  • 举报
回复
declare @StartIP bigint
set @StartIP=(0x7FFFFFFFFFFFFFFF+1)
>>>
常量 0x7FFFFFFFFFFFFFFF非 big 类型, 具体是什么我不清楚, 所以加1後不会产生overflow.

set @startIP= CAST(CAST(0x7FFFFFFFFFFFFFFF as BIGINT)+1 as BIGINT )
这样便会出错了.


我看你有戏 2009-12-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 colacat911 的回复:]
ulong类型
0~18 446,744,073,709,551,615


bigint
-2^63 (-9,223,372,036,854,775,808) 至 2^63-1 (9,223,372,036,854,775,807)

int
-2^31 (-2,147,483,648) 到2^31 - 1 (2,147,483,647)

SQL codeSELECTCONVERT(INT,0x7FFFFFFF),CONVERT(INT,0x7FFFFFFFFFFFFFFF)----------- -----------2147483647-1

(1 行受影响)

至于ulong ee = 0x7FFFFFFFFFFFFFFF+1会报溢出应该是由于0x7FFFFFFFFFFFFFFF是-1的原因

[/Quote]


那为啥 sql语句 bigint的时候不会报错呢,
declare @StartIP bigint
set @StartIP=(0x7FFFFFFFFFFFFFFF+1)


@StartIP的值就直接为0了

忆轩辕 2009-12-28
  • 打赏
  • 举报
回复
ulong类型
0~18 446,744,073,709,551,615


bigint
-2^63 (-9,223,372,036,854,775,808) 至 2^63-1 (9,223,372,036,854,775,807)

int
-2^31 (-2,147,483,648) 到2^31 - 1 (2,147,483,647)



SELECT CONVERT(INT,0x7FFFFFFF),CONVERT(INT,0x7FFFFFFFFFFFFFFF)

----------- -----------
2147483647 -1

(1 行受影响)




至于ulong ee = 0x7FFFFFFFFFFFFFFF+1会报溢出应该是由于0x7FFFFFFFFFFFFFFF是-1的原因
我看你有戏 2009-12-28
  • 打赏
  • 举报
回复
.net里面

ulong ee = 0x7FFFFFFFFFFFFFFF+1;

这样编译的时候会有益处提示的
我看你有戏 2009-12-28
  • 打赏
  • 举报
回复
做题目要仔细啊
guguda2008 2009-12-28
  • 打赏
  • 举报
回复
int 的范围
-2^31 (-2,147,483,648) 到 2^31-1 (2,147,483,647)

这下明白了吧
SQL77 2009-12-28
  • 打赏
  • 举报
回复
晕,还以为上面和下面一样呢,不一样的
我看你有戏 2009-12-28
  • 打赏
  • 举报
回复
第二个其实是超出了bigint的最大正整数范围了的
guguda2008 2009-12-28
  • 打赏
  • 举报
回复
SELECT CONVERT(INT,0x7FFFFFFF),CONVERT(INT,0x7FFFFFFFFFFFFFFF)
--2147483647 -1
--小F-- 2009-12-28
  • 打赏
  • 举报
回复
declare @StartIP int
set @StartIP=(0x7FFFFFFF+1)
print @StartIP


二进制数据转换成int超过int的范围了 而没有超出bigint的范围
SQL77 2009-12-28
  • 打赏
  • 举报
回复
转过来是0?
SQL77 2009-12-28
  • 打赏
  • 举报
回复
set @StartIP=(0x7FFFFFFFFFFFFFFF+1)

你这个转过来超过INT所能表示的最大数了

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧