質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.07%

型変換について質問です。(C++)

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 472

kimtakuya_

score 19

前提・実現したいこと

C++を利用して-250から250の乱数を生成したいが、型変換の問題なのか期待するものが得られません。

発生している問題・エラーメッセージ

なし

該当のソースコード

#include <iostream>
#include <random>


int main() {
    std::random_device rnd;
    //結構な確率で4294967110くらいの大きな数字が返却される
    std::cout << "異常な動作\n";
    for (int i = 0; i < 10; i++) {
        std::cout << (rnd() % 500) - 250 << "\n";
    }

    //500で割るだけなら0~499が返却される
    std::cout << "\n\n正常な動作\n";
    for (int i = 0; i < 10; i++) {
        std::cout << (rnd() % 500) << "\n";
    }
}

試したこと

問題自体は解決してはいてint(rnd() % 500) - 250;とすればほしいものが出力はされるのですが理由が分かりません

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+4

rnd()が返す値の型result_typeunsigned intだからです。
std::random_device

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+3

distributionちゃんとつかえばいいのに

#include <iostream>
#include <random>

int main() {
    std::random_device rnd;
    // -250~250 の一様分布
    std::uniform_int_distribution<> dist(-250,250);
    for (int i = 0; i < 10; i++) {
        std::cout << dist(rnd) << "\n";
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+1

質問への回答ではありませんが、-250 から 250 までの 501種類の値が得たいのなら、
int(rnd() % 501) - 250 にしないと、250 という値は得られません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

こんにちは。

unsignedからunsinedを引いた結果もまたunsignedです。
なので結果が負になる場合は、アンダーフローが発生し巨大な値になるはずです。

整数変換のルールを理解するの「通常の算術型変換」にある下記ルールによるものと思います。

1. 両方のオペランドが同じ型をもつ場合、更なる型変換は行わない。


【追記】
asmさんのご指摘より、当回答は間違いでしたので訂正させて下さい。

unsigned - signed(250はint型です)なので、同ページにある下記ルールが適用されそうです。

3. そうでない場合、符号無し整数型を持つオペランドが、他方のオペランドの整数変換の順位より高い又は等しい順位をもつならば、符号付き整数型をもつオペランドを、符号無し整数型をもつオペランドの型に変換する。

つまり、signedをunsignedへ変換するので、結局unsigned - unsignedとなりアンダーフローするということのようです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/04/21 13:59 編集

    横からすいません。疑問なのですが
    http://eel.is/c++draft/lex.icon#3 より
    サフィックスのない十進整数リテラルは符号付きになるはずですよね?

    キャンセル

  • 2020/04/21 14:51

    asmさん
    あ、たしかにその通りですね!!
    ならば、unsigined - signedだから、他のルールが適用されている筈ですね。
    ご指摘ありがとうございます。

    キャンセル

  • 2020/04/21 19:12

    数値リテラル側にlサフィックス付けると結果が変わる事が不思議でしたが
    なるほど、
    unsigned intとintだとunsigned intに揃えられ
    unsigned intとlongだとlongに揃えられる感じなのですね。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.07%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る