Cでcompareが-1,0,1を返す理由

JavaのAPIリファレンスでBigDecimalのcompareToを見ていて気づいたのだけれど、
BigDecimalの値の大小を比較する際には以下のように行えとある。
BigDecimal bd = ...

...

// bd > 1
if (bd.compareTo(BigDecimal.ONE) > 0) {

// bd == 1
} else if (bc.compareTo(BigDecimal.ONE) == 0) {

// bd < 1
} else if (bc.compareTo(BigDecimal.ONE) < 0) {

...

特に驚くようなこともないけれど、一歩引いて考えてみると
記法としてはとても巧妙なものだと気づく。
つまり、右辺を0にすると比較演算子がそのままcompareToの比較関係を表しているのだ。
演算子オーバーロードに似ていると言ったら言いすぎだろうか。

Cでstrcmpやmemcmpが-1,0,1を返すのはまあそんなもんかなくらいに思っていたけど、
なんだか理由がわかった気がする。

2 件のコメント:

  1. C(gcc 4.9.2…というか、glibc 2.20)では、strcmpもmemcmpも一致した時に0を返し、不一致時は正数か負数を返す、が仕様だと思いますよ。実装にも依ると思いますが、基本1バイトずつ引き算してたんじゃないかな。
    と思い以下を試しました。

    #include
    #include
    int main(void){
    char *str1 = "hoge", *str2 = "piyo";
    int ret1 = strcmp(str1, str2), ret2 = memcmp(str1, str2, 3);
    printf("%d %d¥n", ret1, ret2);
    return 0;
    }

    結果。
    -8 -8
    'h' => 0x68
    'p' => 0x70
    なので、やはり引き算してるっぽい。
    ということで、h->aにしてやってみたら
    -15 -15
    'a' => 0x61
    なので、やはり引き算してそうです。

    返信削除
    返信
    1. そうですね。
      正確には-1,1ではなく、負数、正数が仕様ですよね。
      なんとも、微妙なタイトルになってしまいました。。。

      削除