Re: Unsigned Modulo
Re: Unsigned Modulo
- Subject: Re: Unsigned Modulo
- From: Bavarious <email@hidden>
- Date: Wed, 12 Aug 2015 08:44:05 -0300
> On Aug 12, 2015, at 07:12, Gerriet M. Denkmann <email@hidden> wrote:
>
> OS X 10.10.4, Xcode 7 beta 3
>
> This code produces some (for me) unexpected results:
>
> NSUInteger unsignedSize = 3;
> NSInteger signedSize = 3;
>
> for ( NSInteger rawValue = -6; rawValue < 5; rawValue++ )
> {
> NSInteger modValueU = rawValue;
> NSInteger modValueS = rawValue;
> modValueU %= unsignedSize;
> modValueS %= signedSize;
> fprintf(stderr,"rawValue %+2ld modValueU %+2ld modValueS %+2ld\n", rawValue, modValueU, modValueS);
> };
>
> rawValue -6 modValueU +1 modValueS +0 expected modValueU = 0
> rawValue -5 modValueU +2 modValueS -2 expected modValueU = 1
> rawValue -4 modValueU +0 modValueS -1 expected modValueU = 2
> rawValue -3 modValueU +1 modValueS +0 expected modValueU = 0
> rawValue -2 modValueU +2 modValueS -2 expected modValueU = 1
> rawValue -1 modValueU +0 modValueS -1 expected modValueU = 2
> rawValue +0 modValueU +0 modValueS +0
> rawValue +1 modValueU +1 modValueS +1
> rawValue +2 modValueU +2 modValueS +2
> rawValue +3 modValueU +0 modValueS +0
> rawValue +4 modValueU +1 modValueS +1
>
> Probably the answer is: works as documented (but I can’t figure out the rule it is following).
Hrm, scratch my previous answer. I misunderstood the issue.
With
modValueU %= unsignedSize
you have
modValueU = modValueU % unsignedSize
where modValueU is a signed integer and unsignedSize is an unsigned integer. When an expression mixes both signed and unsigned, C99 6.3.1.8p1 says that
‘if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type’
which means that modValueU is converted to NSUInteger.
When modValueU = -6, the corresponding unsigned value is 18446744073709551610 (= 2^64 - 6), which is congruent to 1 modulo 3.
>
> But even if so: why are there no warnings, compiling with these flags:
>
> CLANG_WARN_IMPLICIT_SIGN_CONVERSION
> GCC_WARN_ABOUT_POINTER_SIGNEDNESS
> GCC_WARN_SIGN_COMPARE
>
> Gerriet.
Yeah, something’s fishy. I get no warning with -Wsign-conversion and your code. However, if I change
modValueU %= unsignedSize;
to
modValueU = modValueU % unsignedSize;
I get the following warning:
‘warning: implicit conversion changes signedness: 'unsigned long' to 'NSInteger' (aka 'long') [-Wsign-conversion]’
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden