max(a,b)
を実装する方法が議論されています。では、更に条件を厳しくして、「条件分岐も算術演算も使わずに」
max(a,b)
を実装することはできるでしょうか?も
ち
ろ
ん
可
能
で
す
回
答
例
は
以
下
に
あ
り
ま
す
なぜ、「もちろん」なのか。CPUがANDやOR、NOTのようなデジタルな論理回路から構成されています。であれば、当然、ビット演算(ビットシフトと
&
, |
, ^
)を使って、max(a, b)
を実装することも可能なわけです。こんな感じ。#include <stdio.h> #define BIT(n, pos) (((n) >> (pos)) & 1) static int mymax(int a, int b) { int islt = BIT(a, 31) & (BIT(b, 31) ^ 1); int iseq = BIT(a, 31) ^ BIT(b, 31) ^ 1; #define CHECK_BIT(pos) do { \ islt |= iseq & (BIT(a, pos) ^ 1) & BIT(b, pos); \ iseq &= BIT(a, pos) ^ BIT(b, pos) ^ 1; \ } while (0) CHECK_BIT(30); CHECK_BIT(29); CHECK_BIT(28); CHECK_BIT(27); CHECK_BIT(26); CHECK_BIT(25); CHECK_BIT(24); CHECK_BIT(23); CHECK_BIT(22); CHECK_BIT(21); CHECK_BIT(20); CHECK_BIT(19); CHECK_BIT(18); CHECK_BIT(17); CHECK_BIT(16); CHECK_BIT(15); CHECK_BIT(14); CHECK_BIT(13); CHECK_BIT(12); CHECK_BIT(11); CHECK_BIT(10); CHECK_BIT(9); CHECK_BIT(8); CHECK_BIT(7); CHECK_BIT(6); CHECK_BIT(5); CHECK_BIT(4); CHECK_BIT(3); CHECK_BIT(2); CHECK_BIT(1); CHECK_BIT(0); #undef CHECK_BIT /* extend flag to 32-bit mask */ islt <<= 31; islt >>= 31; return (a & (islt ^ 0xffffffff)) | (b & islt); } int main(int argc, char **argv) { int a, b; if (argc != 3) { fprintf(stderr, "Usage: %s a b\n", argv[0]); return 1; } if (sscanf(argv[1], "%d", &a) != 1) { fprintf(stderr, "%s is not a number\n", argv[1]); return 1; } if (sscanf(argv[2], "%d", &b) != 1) { fprintf(stderr, "%s is not a number\n", argv[2]); return 0; } printf("max(%d,%d) is %d\n", a, b, mymax(a, b)); return 0; }
No comments:
Post a Comment