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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Q&A

解決済

1回答

544閲覧

Rustで立っているビットで一番端にあるものの位置を求めるプログラムが想定通り動かない

_Victorique__

総合スコア1392

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

0グッド

0クリップ

投稿2023/05/18 16:45

編集2023/05/18 19:58

こちらのページを参考に一番端の立っているビットの位置を求めるプログラムを実装しています。
参考にしているページはC#ですがRustで書き直しています。
https://ac-as.net/how-to-get-right-most-bit/

実装は上手くいってそうなんですけどある値を境にオーバーフローしてしまいます。
具体的には 1 ~ 6 までの値はオーバーフローせずに正常な値を得ることができます。
7 以降になるとオーバーフローしてしまいます。
どこか実装でミスをしているのか、そもそもアルゴリズムに対する理解が違うのか(6ビット区切りだからそもそも7桁以降は求められないのか?)
その他ネットで色々と情報を探しましたが手掛かりはありませんでした。
何かヒントがあれば教えていただけないでしょうか?

Rust

1fn create_table() -> Vec<usize> { 2 let mut table = vec![0usize; 64]; 3 let mut hash = 0x03F566ED27179461u64; 4 for i in 0..64usize { 5 table[(hash >> 58) as usize] = i; 6 hash <<= 1; 7 } 8 table 9} 10 11fn count_bit(n: u64) -> usize { 12 if n == 0 { 13 return 64; 14 } 15 let y = ((n as i64) & -(n as i64)) as u64; 16 let index = ((y*0x03F566ED27179461u64) >> 58) as u64; 17 let table = create_table(); 18 table[index as usize] 19} 20 21fn main() { 22 for i in 0..=7 { 23 let n = 1u64 << i; 24 println!("{}", count_bit(n)); // Error if i == 7 25 } 26}

エラーログ

Log

10 21 32 43 54 65 76 8thread 'main' panicked at 'attempt to multiply with overflow', src/main.rs:127:18 9note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

追記

なぜかpaizaの実行環境ではエラーにならず63まで正常に表示されました。。。
バージョンによる差異なのでしょうか。。。?

イメージ説明

Paiza -> rustc 1.59.0
Local -> rustc 1.62.0

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

melian

2023/05/18 20:38

最適化オプション(-O)を付けてビルドしてください。 $ rustc -O ... Understanding arithmetic overflow/underflows in Rust and Solana smart contracts https://medium.com/coinmonks/understanding-arithmetic-overflow-underflows-in-rust-and-solana-smart-contracts-9f3c9802dc45 > Rust does not prevent Integer overflow/underflow > > However, in release (or optimization) mode, Rust silently ignores this behavior by default and computes two’s complement wrapping (e.g., 255+1 becomes 0 for an u8 integer).
退会済みユーザー

退会済みユーザー

2023/05/18 22:00

C# のタグがついてますが、関係ないので外してください。
_Victorique__

2023/05/19 05:25

> SurferOnWww 元のコードがC#なので関係ないとは言えないので外しません。異議があるのであれば運営に直接お願いします。
guest

回答1

0

ベストアンサー

attempt to multiply with overflow は、デバッグビルド環境においてオーバーフローが発生したときに発生するパニックです。
元の行番号が不明ですが、おそらく示されているコードでは16行目の y*0x03F566ED27179461u64 の箇所でオーバーフローしていると思われます。

Rustでは、掛け算で故意にオーバーフローさせて結果の上のビットを切り捨てる場合には、 wrapping_mul を使用します。
https://doc.rust-lang.org/std/primitive.i64.html#method.wrapping_mul
同様のメソッドが他の四則演算にもあります。

投稿2023/05/19 00:12

IgaguriMK

総合スコア148

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

_Victorique__

2023/05/19 05:28

C#とRustで動作が違うのを全く考えてませんでした。 上記メソッドを利用して上手く行きました!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問