[前][次][番号順一覧][スレッド一覧]

ruby-changes:53459

From: shyouhei <ko1@a...>
Date: Mon, 12 Nov 2018 10:08:43 +0900 (JST)
Subject: [ruby-changes:53459] shyouhei:r65675 (trunk): ~(unsigned char) is not unsigned char

shyouhei	2018-11-12 10:08:35 +0900 (Mon, 12 Nov 2018)

  New Revision: 65675

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=65675

  Log:
    ~(unsigned char) is not unsigned char
    
    The unary ~ operator excercises integer promotion of the operand
    _before_ actually applying bitwise complement (cf: ISO/IEC 9899:1990
    section 6.3.3.3).  Which means `~buf[i]` is in fact
    `(int)~(int)buf[i]`.
    
    The problem is, when buf[i] is 0xFF:
    
          buf[i]        0xFF
     (int)buf[i] 0x0000_00FF
    ~(int)buf[i] 0xFFFF_FF00 This is -256, out of unsigned char range.
    
    The proposed fix is to change the char signed.  By doing so,
    
                       buf[i]        0xFF
          (signed char)buf[i]        0xFF
     (int)(signed char)buf[i] 0xFFFF_FFFF
    ~(int)(signed char)buf[i] 0x0000_0000 This is 0, does not overflow.

  Modified files:
    trunk/bignum.c
Index: bignum.c
===================================================================
--- bignum.c	(revision 65674)
+++ bignum.c	(revision 65675)
@@ -616,8 +616,12 @@ static int https://github.com/ruby/ruby/blob/trunk/bignum.c#L616
 bytes_2comp(unsigned char *buf, size_t len)
 {
     size_t i;
-    for (i = 0; i < len; i++)
-        buf[i] = ~buf[i];
+    for (i = 0; i < len; i++) {
+        signed char c = buf[i];
+        signed int d = ~c;
+        unsigned int e = d & 0xFF;
+        buf[i] = e;
+    }
     for (i = 0; i < len; i++) {
         buf[i]++;
         if (buf[i] != 0)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]