• ベストアンサー

Math.pow

Javascriptでべき乗の余りを表で出力するスクリプトを書いているのですが、大きな値になると計算結果が正しく出力されません。 いろいろ検証してみたところ、大きな値になるとべき乗の計算結果が正しく出力されないことが判明しました。 例えば、31の11乗を計算すると 25408476896404831 ですが、Javascriptで31の11乗を計算すると a=Math.pow(31,11); document.write(a); で計算結果を出力すると 25408476896404830 になってしまいます。 結果としては、べき乗の余りを出力したいので 例えば、31の11乗を33で割った余り Math.pow(31,11)%33 が「31」と正しく出力されればよいのですが・・・。「32」と出力されてしまいます。大きな整数値の計算は、何か特別な工夫が必要なのでしょうか? アドバイスをよろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

特定の計算するだけなら function f(n,p,m){ // 本当は n,p,mが自然数かどうかチェックしたい。 if (p > 1){ var t = Math.pow(2,Math.floor(Math.log(p,2))); return ((f(n,p - t,m) * f(n,t,m)) % m); }else if(p == 1){ return n; }else if(p == 0){ return 1; } } alert(f(31,11,33)); //31 みたいな計算も出来るかな、と思う。 No.1のような汎用性はないけど。、とどうでもいい独り言を書いてみる。

whitetooth
質問者

お礼

いえいえ、参考になりますよ。ありがとうございます。 何だかよく分からないけれど、うまく動きます。 やりたいことに応用できそうです。 でも、対数を利用して・・・Math.log(p,2)というのはどういう意味だ?

その他の回答 (4)

回答No.5

私も全く同じ問題を調べていたのですが、 回答No.3のwikiのやつをそのままjavascriptに置き換えたら うまくいきました。

回答No.4

>でも、対数を利用して・・・Math.log(p,2)というのはどういう意味だ? マジですまん。無視してくれ。 >途中で剰余をとる をやろうとしたんだが,アルゴリズムも間違っている上に、 Math.log(a,b)を bを底としたlogだと思い込んでいた。 #関数がありませんって言われないんで #てっきり他の言語同様あるのかと思ってlog(8,2)で3を期待したら出てこなかったorz

  • Werner
  • ベストアンサー率53% (395/735)
回答No.3

このページの計算方法を見ればいいんじゃないかな。 べき剰余 - Wikipedia http://ja.wikipedia.org/wiki/%E3%81%B9%E3%81%8D%E5%89%B0%E4%BD%99

whitetooth
質問者

お礼

参考にさせていただきます。 ありがとうございます。

  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.1

javascriptでの整数の有効桁数は2^53(十進で16桁程度)らしいので、それ以上の桁数になると桁落ちする結果といえます。 これは、計算機がもっている限界で(大小あっても必ず有限)、単純に考えれば8桁の電卓で10桁の剰余を求める計算をすると、結果が正しくないと言っているようなもの。 なので、桁数を区切って、べき乗と剰余を計算する部分を自作するしかないのでは? (↓)このあたりが参考になりそう。  http://deztec.jp/x/05/faireal/25-index.html

whitetooth
質問者

お礼

なるほど・・・勉強してみます。 ありがとうございました。

関連するQ&A

  • 16進数の文字列

    16進数の文字列をそれと同値な整数値へ変換する関数をかけという問題なのですが、 この場合文字列を読み込んで、例えば読み込んだ値がABだとした場合、 A*16の1乗+B*16の0乗 を計算する関数を作ればよいのだと思うんですが、 それぞれの値をべき乗する関数も必要になってくると考えています。 そこで問題なのですが、べき乗の関数を作ったとして、それぞれの値(こんかいはAとB)にそれぞれのべき乗した値をかけてやるには、どういった方法があるのでしょうか? 回答よろしくお願いします。

  • Math.sin(30) を度で

    Math.sin(30) で取得できるのはラジアンの値ですよね? そこで Math.sin(30) * 180 / Math.PI で度にしたいのですが、 結果は -56.61004208597725 になってしまいます。 なぜ 0.5 にならないのでしょうか、また、正しくは どう計算すればいいのでしょうか。よろしくお願いします。

  • C言語のプログラムについて質問です。

    C言語のプログラムについて質問です。 プログラムでどうしても2.2乗という少数のべき乗を使用しなければいけなくなったのですが、 POW関数では遅くて使い物になりません。 そこで、べき乗の高速化について調べたのですが、整数のべき乗の高速化しか出てきませんでした。 少数のべき乗の高速化アルゴリズムというものはあるのでしょうか?

  • integerクラスとMathクラス

    適当な整数numをキーボードから入力し、その回数だけ0から360までの整数をランダムに発生させ、その整数を角度(弧度法)とみなしたとき、その正接(tan)が最大のとなる整数を表示するプログラム を以下の手順で下記に作成した結果、角度が同じ値になります。これはどうしてですか?また、手順通りのプログラムにするにはどのようなプログラムて適切ですか?     手順      (1)最大値となる角度を代入する整数型の変数maxを初期値-90で定義する。      (2)乱数を発生させる回数を入力する。      (3)0から360までの整数を、乱数を使って1つ発生させ、整数型の変数degに保存。この値を表       示する。      (4)角度degをラジアンに変換し、実数型の変数radに代入し、表示する。変換は             rad = deg * Math.PI/180.0 (Math.PIは円周率を表す)       で行なうことができる。ただし、実際のプログラムでは上式をそのまま書くのではなく、変数       の型に注意して記述すること。      (5)radを用いて正接(tan)を計算する。      (6)maxから計算されるtanの値と比較し、(4)の結果の方が大きければmaxをdegに書き換え       る。      (7)(2)から(5)を入力した回数になるまで繰り返す      (8)maxを表示する。import java.io.*; class Kakudo3 { public static void main(String args[]) throws IOException { int max = -90; System.out.println("整数を入力"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str1 = br.readLine(); int num = Integer.parseInt(str1); int deg =(int)(Math.random()*360); for(int i=0; i<num; i++){ System.out.print(deg+","); } double rad = deg*Math.PI/180.0; Math.tan(rad); } }

    • ベストアンサー
    • Java
  • エクセル2000でべき乗数値計算

      A1セルにN:整数の値が入っているとします。 A2セルにk:数値データが入っているとします。 A3セルに利息などの数値0.02に1を足したもの(元利合計):例えば1.02が入っているとします。 A4セルに計算結果: k(A2セル)の_1.02(A3セル)のN乗【A1セル乗】 という値を入れたい。 どのようにA4に計算式を書けばよいか。 回答をよろしくお願いします。

  • 0の0乗は1、にしたい(続き)

    http://oshiete1.goo.ne.jp/qa4347011.html の続きです。 0の0乗の値について、不定だとか未定義だとかの意見があります。 でも、1と定義しても無矛盾だし、1以外では矛盾が生じます。 そこで、べき乗(累乗)の定義を  x^0=1  x^n=x^(n-1)×x (nは自然数) としてしまえば、0^0は当然1になります。 #負の整数乗、有理数乗、実数乗などへの拡張は、従来のような方法で行われるとします。 この定義の仕方には、問題があるのでしょうか? なお、常識的には…という話は、遠慮願います。 #Wikipediaも変わりますので。 これまでの議論で主張したこと: (1) 従来のべき乗の定義は、1から始まるので不自然。加法や乗法は0から始まる。 (2) 従来のべき乗の定義との違いは、0^0の値についてだけである。 (3) 0及び正の整数乗は、すべての実数に対して計算できる。負の整数乗は正の整数乗の逆数として計算できる。(0のべき乗以外) (4) 0^y=0という式はy<0で成立しない。それをy=0まで拡張するのは不自然。 (5) 0^0=0は、関数0^yについて、y=0で連続性が破綻しないから不適当。 (6) lim[x→0,y→0]x^yは不定であるが、0^0=1と矛盾しない。 (7) x^y形式の連続な式で、x=0、y=0の時、その値が1以外に定まる式は存在しない。 (8) 1である根拠は、0^0=0^(-0)=1/0^0。 たぶん、このどれかが成立しなければ、最初の定義は怪しくなります。 #(7)は、表現に不備がある可能性があります。

  •  Javaでのある数の小数点乗について

     Javaでのある数の小数点乗について  数学での計算をJavaを使って計算している所です。Javaの中でもDoubleを使うのではなく、BIgDecimalクラスを使って計算をしています。しかし、BigDecimalの値をBigDecimal乗するという事は出来ないですよね? Math.powを使えばDouble型のDouble乗は出来ますが…  そこで、任意の精度で小数点の小数点乗を求める方法は無いでしょうか? 必要ないかもしれませんが参考までに 言語:Java OS:MacOS 10.5

    • ベストアンサー
    • Java
  • 計算が簡単になる工夫はあるのか

    a=9+98+987+9876+98765+987654+9876543+98765432 b=12345678+1234567+123456+12345+1234+123+12+1 のとき、a/bを計算したとき、整数部分を求めよ。 何か工夫して計算する問題だと思うのですが、それが何か わかりません。 考え方として2つあると思います。 1つ目は、a,bの値を工夫してもとめて、実際に割り算をする。 しかし、a,bの値を工夫して求めるまでもないように思うので、 この方法ではないように思う。 2つ目は、a,bの値を求めないで何か工夫する方法。 この問題の解法はこの2つ目だと思うが、どうすればいいかは 思いつきません。 よろしく、アドバイスお願いします。

  • powで1 番目の引数が負の無限大で 2 番目の引数が負の有限の奇数の整数の場合

    java初心者です。 初歩的な質問ですみません。 http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/java/lang/Math.html powが使えなかったので↑のサイトに書いてあることを参考にべき乗を計算するメソッドを作っているのですが、難しいところがあってわかりません。(・・;) ●1 番目の引数が負のゼロで 2 番目の引数が正の有限の奇数の整数、または 1 番目の引数が負の無限大で 2 番目の引数が負の有限の奇数の整数の場合、結果は負のゼロになります。 ●1 番目の引数が負のゼロで 2 番目の引数が負の有限の奇数の整数、または 1 番目の引数が負の無限大で 2 番目の引数が負の有限の奇数の整数の場合、結果は負の無限大になります。 と書いてありました。 1 番目の引数が負の無限大で 2 番目の引数が負の有限の奇数の整数の場合、結果はどうすればいいのですか?

  • プログラミング

    教えてください! キーボードから キーボードから 2つの実数 aと b〔double 型〕を入力し、 Math クラスのメ ソッド double pow(a, b);を用いて aの b乗を求め 画面に出力しなさい。 〔実行例〕 aの b乗を求めます 実数 aの値を入力してください 2 実数 bの値を入力してください 3 2.0 の 3.0 乗は 8.0 です

    • ベストアンサー
    • Java