How does division "/" = work for integer types?
169 次查看(过去 30 天)
显示 更早的评论
In doing some work with integers in R2021A I noticed something relatively strange, namely that if A and B are unsigned integers and A >= B/2, then A/B = 1. Before today, I was not aware of this "rounding". In fact this doesn't quite jive with the documentation. In particular, uint32(1)/uint32(2) gives 1, wheras bitshift(uint32(1),-1) gives 0. Per the documentation https://www.mathworks.com/help/matlab/ref/bitshift.html, a bitshift of -1 should give the same result as dividing by 2. Is this expected behavior? I've attached a screenshot.
0 个评论
采纳的回答
Chunru
2021-6-16
编辑:Chunru
2021-6-16
MATLAB rounds the results when dividing integer data types. That is to say:
uint32(1) /uint32(2) = round(1/2) = round(0.5) =1
uint32(1)/uint32(2)
uint32(10)/uint32(3)
uint32(5)/uint32(2)
3 个评论
Walter Roberson
2023-2-17
Integer division has no "natural" behaviour for remainders (except perhaps to offer to return the remainder separately).
What does "truncate" mean, exactly? Is it "round towards 0", or is it "floor" ? And should the result be different for 5/-2 than for -5/2 ?
更多回答(2 个)
Steven Lord
2021-6-16
See the "Creating Integer Data" and "Arithmetic Operations on Integer Classes" sections on this documentation page.
0 个评论
uno
2023-2-17
Stumbled on this since I've just encontered the same issue. Totally nuts and I believe should be fixed.
Seems at the moment the solution is to use the idivide() function.
15 个评论
Thomas Bewley
2024-4-19
编辑:Thomas Bewley
2024-4-19
Paul - Yes, Fortran is consistent with C and Ada and all C-like programs that I am aware of (Rust, etc) in this regard. Yet, still inexplicably, in modern Matlab:
>> a=int8(-8); b=int8(3); a/b
ans =
int8
-3
Matlab is apparently the only programming language in the world today which does not do integer division in the standard way: "Integer division and remainder are defined by the relation A = (A/B)*B + (A rem B), where (A rem B) has the sign of A and an absolute value less than the absolute value of B. Integer division satisfies the identity (-A)/B = -(A/B) = A/(-B)."
AFAIK, rereading the above thread, Walter Roberson still hasn't motivated why Matlab implements its nonstandard choice (rounding to the nearest integer), which (I believe it can be reasonably argued) is error-prone due to its failure to satisfy the above stated standard definition, other than to state his preference for yet a third definition (rounding towards negative infinity, which fails to satisfy the above stated identity) as his humble opinion. I request that a committee of persons who are experienced in modern integer programming applications at Mathworks review the arguments laid out in this thread, and come up with a more deliberate path forward.
Steven Lord
2024-4-19
Let's look at one of the examples you posted:
a=uint8(7);
b=uint8(4);
answer1=a/b
answer2=idivide(a,b)
Would it be useful if a/b were to give the same answer as uint8(double(a)/double(b)), since both a and b are exactly representable in double precision? In other words, should it matter if you convert between double and uint8 before or after performing the division? [This same holds for the six smaller integer types; 64-bit integers have the complication that not all int64 or uint64 values are exactly representable in double precision.]
answer3 = uint8(double(a)/double(b))
answer3b = uint8(7/4)
If we look at a slightly different example:
answer4a = uint8(5/4)
answer4b = uint8(5)/uint8(4)
From the documentation: "If the number being converted to an integer has a fractional part, MATLAB rounds to the nearest integer."
By the way, if you're looking for integer arithmetic in MATLAB (using the operators) to exactly match C's behavior, it doesn't. Integer arithmetic in MATLAB saturates for both signed and unsigned integers instead of wrapping for unsigned integers like C. [And doing a little archaeology as well as remembering some of the discussions, "saturate or wrap" was quite vigorously debated internally when we first introduced integer arithmetic back in 2004 in release R14.]
x = intmax('uint8')
y = x+1 % saturates so y is the same as x, not wrapped to 0
If you're doing image processing on integer image data x, x+1 always being greater than or equal to x is probably a Good Thing.
But if you disagree with the choice of behavior for the backslash operator, you have a solution that you've already identified: use idivide. If I recall correctly, providing C style division was the main motivating factor for its existence!
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!