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

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

ただいまの
回答率

90.61%

  • Ruby

    7317questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

N(>2)進法の足し算について

解決済

回答 2

投稿

  • 評価
  • クリップ 3
  • VIEW 759

manman

score 257

以下のように3進法で足し算を行おうとしました。
irb(main):001:0> a = 4
=> 4
irb(main):002:0> b = 2
=> 2
irb(main):003:0> a = a.to_s(3)
=> "11"
irb(main):004:0> b = b.to_s(3)
=> "2"
irb(main):005:0> a + b
=> "112"
irb(main):006:0> (a.to_i(3) + b.to_i(3)).to_s(3)
=> "20"
a + b で思った結果がかえってこなかったので、
(a.to_i(3) + b.to_i(3)).to_s(3)で計算しました。

一般にN(>2)進法の計算するには、
.to_i(N)→計算→.to_s(N)
としないとダメなのでしょうか?
もっと簡単にできないのでしょうか?

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+1

a.to_s(3)の結果は文字列なので、+は文字列同士の連結になってしまいます。

Rubyでは(他のほとんどの言語でも)3進法の計算は出来ません。一旦は2進法に直して計算することになります。
.to_i(N)→計算→.to_s(N)
としないとダメなのでしょうか?
そうですね。

そういうクラスを作ればいいかと思います。
class Sanshin
  attr_reader :value
  def initialize(x)
    case x
    when Numeric
      @value = x
    when String
      @value = x.to_i(3)
    end
  end
  def +(other)
    case other
    when Sanshin
      Sanshin.new(@value + other.value)
    when Numeric
      Sanshin.new(@value + other)
    when String
      Sanshin.new(@value + other.to_i(3))
    end
  end
  def to_s
    @value.to_s(3)
  end
  def inspect
    to_s
  end
end
def Sanshin(x)
  Sanshin.new(x)
end

a = Sanshin(3)
b = Sanshin(2)
p a+b #=> 12

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/05/17 12:11

    (細かいことを申し上げて悪いのですが、)2行目「一旦は2進法に直して計算することになります。」は「一旦は3進法に直して計算することになります。」ではないでしょうか?

    キャンセル

  • 2015/05/17 12:13

    書かれているとおりです。私の勘違いでした。

    キャンセル

+1

n 進数というのは、 整数を文字列として表記するときの事です。
数値演算処理は常に *整数として処理* をする必要があります。

a.to_s(3), b.to_s(3) の結果はいずれも 文字列なので
a.to_s(3) + b.to_s(3) は 文字列としての + 演算処理となります。
整数としての演算にはなりません。

"1 + 10" を計算するとき、通常は 10 進でおこないます。
これは、 
"1" を 10 進数で解釈したときの整数値 + "10" を 10 進数で解釈したときの整数値
の結果を 10 進数で表す
を行い "11" を得ることになります。
ruby のコードで書けば
("1".to_i(10) + "10".to_i(10)).to_s(10)
ということです。

異なる N 進表記の値同士を演算して、その結果をさらに異なる N 進表記で表すということも可能です。
(10.to_i(10) + 10.to_i(2)).to_s(3)
=> (10 + 2).to_s(3)
=> 12.to_s(3)
=> "110"

時間の表示は単純な N 進ではありません。 
"1:23:59" (1時間 23 分 59 秒) + "0:0:2" (2秒) を計算する場合は
時分秒の表記を 秒だけでの値に変換してから, 秒の単位で数値演算をし、その結果を 時分秒 の表示にします。
(1 * 60 * 60 + 23 * 60 + 59) 秒 + 2 秒
=> (3600 + 1380 + 59) + 2 秒
=> (5039 + 2) 秒
=> 5041 秒
=> (3600 + 1441) 秒
=> 3600 + 24 + 60 + 1 秒
=> 1:23:01 (1時間23分1秒)

数値の表示と 数値の値は別のものだということは普段は明確に意識していないですが、
コンピューターでの計算の場合は常に区別をすることが必要です。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/05/17 19:20

    文字列と数値の区別が大切だとわかりました。例えば、(12359)11の次の次の数を次のように計算しました。
    irb(main):001:0> ('12359'.to_i(11)+2).to_s(11)
    => "12360"

    キャンセル

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

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

関連した質問

  • 解決済

    1989年東京大学の入試問題について

    10^210 / (10^10 + 3) の整数部分の桁数と、 一の位の数字を求めよ。 ただし 3^21 = 10460353203 を用いてよい。 数学的解法によらないで、プロ

  • 解決済

    次の次の…の値をかえすには?

    以下の irb(main):002:0 で行なっていることを簡単にできないでしょうか? irb(main):001:0> i = 100 => 100 irb(main):002

  • 解決済

    Rubyのgsubについて質問です

    こんばんは。 Ruby gsubメソッドを用いて文字コードの置換を行う際に 気になった点があったので、質問させて下さい。 gsubの第一引数の正規表現の中での角かっこを用いた指定

  • 解決済

    ファイル読み込みの仕様について

    Rubyでファイルを読み込みその内容を出力したいのですが,その際のしようと思われる部分で困っております. 想定としては下記のプログラムでテキストの内容を読み込み出力したいと考えて

  • 解決済

    Rubyのmatchメソッドを使って文字をnilが返らず取得するよい方法

    前提・実現したいこと Ruby2.2でmatchメソッドを使って特定文字列の抜き出し処理を実装しました。 マッチしなかった場合には、空文字"" が返るようにしています。

  • 解決済

    Ruby で基準時刻から時刻を加算、減算する方法

    イタリックテキスト###前提・実現したいこと 今、t に基準となる時刻が入っています(19:38)。 これにプログラムで取得した時差tmp(1時間単位)を加算、減算したいのです

  • 解決済

    to_f の結果が0なら空白にしたい

    to_fする前にでも良いのですが ワンライナーでかけないでしょうか?

  • 解決済

    Ruby ハッシュのキーを変数で使いたい

    前提・実現したいこと Rubyの初心者です。 ハッシュのキーを変数で利用したいのですが、nilが帰ってきてしまいます。 R[:I]のように直接シンボルを書かずに、キーを変数で使

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

  • Ruby

    7317questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。