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

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

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

1634閲覧

4を3にする方法がわからない

aaaaaaaa

総合スコア501

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2018/08/03 10:01

編集2018/08/06 09:59

下記のソースは、8進数18桁の777777777777777777を10進数に変換する処理です。
算出する答えは、18014398509481984(1.8014398509482E+16)です。念のためこちらのサイトで答え合わせをしたところ、

10進数 18014398509481984

(詳細な計算は、18014398509481983)

とありました。下一桁目が4で、詳細な計算をすると3になっています。この詳細な計算によって得られる数値は、どうすれば算出できるのだろうと思い諸々と調べてみるとまだそれが正解なのかは、わかりませんが、
BCMATH関数を使えば(変換する数値が18桁なので32bit環境だとdoubleになってしまったのか、
15桁以上だと指数表記になってしまいそれが何か影響を与えているのか分かりませんが、
それなら大きい桁数を扱えるBC関数を、と思いました。)どうにかなるのかもと思い計算処理にBCMATH関数を使いました。
しかし、最後の加算処理部分で躓いてしまいました。思いつく限りのことを書いては消し書いては消しを続けてついに思いつかなくなったので質問に至りました。
for文ではなくarray_sumとBCMATH関数の併用でどうにかならないかなとも思ったのですが、なぜか算出される値が0となってしまいます。

php

1 2 var_dump((int)("777777777777777777")); 3 $nsinsu = 8; 4 $henkan_suuzi = "777777777777777777";//8進数18桁 5 $result = preg_split("//", $henkan_suuzi,-1,PREG_SPLIT_NO_EMPTY); 6 print var_dump($result); 7 $kazu = count($result); 8 print "<p>●配列の数:".$kazu."</p>"; 9 10 //for文内の初期化式であるpow()は、第一引数が、基数(つまり$nsinsu)、第二引数が指数。一文字ずつに分割されたn進数の数字が代入された$resultに対してかけるべき指数を算出。 11 for($i=0,$bekizyo = bcpow($nsinsu,$kazu-1);$kazu > $i;$i++){ 12 if($i !== 0) { 13 $bekizyo = bcdiv($bekizyo,$nsinsu); 14 } 15 print "計算式:".$bekizyo."*".$result[$i]."<hr>"; 16 $zyusinsu[] = bcmul($bekizyo,$result[$i]); 17 } 18 print var_dump($zyusinsu); 19 20 //上手く算出されないのでコメントアウト 21 //$aaa = array_sum($zyusinsu); 22 //$zero = "0"; 23 //bcaddで計算 24 //$bbb= bcmul($aaa,$zero);//なぜか0になる 25 //print "<hr>答え".$bbb."<hr>"; 26 27 //※加算処理でなんとかBCMATH関数を使いたい。 28 //配列の数値を加算。 29 //zyusinsu[0]+zyusinsu[1]+zyusinsu[2]+zyusinsu[3]+zyusinsu[4]... 30 //配列の数だけ、zyusinsu[0]に1番目以降の配列の値を加算させる。 31 for($i=1;$i<count($zyusinsu);$i++) { 32 $zyusinsu[0] += $zyusinsu[$i]; 33 } 34 //print $zyusinsu[0]; 35 36 if(preg_match("/E/",$zyusinsu[0])===1) { 37 $zyusinsu[0] = sprintf("%.0f",$zyusinsu[0]); 38 } 39 print "<hr>".$zyusinsu[0];

いったいどうすると加算処理部分にBCMATH関数が使えるようになり、詳細な計算で下一桁目が3になるのでしょうか。

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

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

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

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

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

m.ts10806

2018/08/03 10:36

「詳細な計算」って何でしょうか。インデントぐちゃぐちゃなコードで読む気が起きないので、整理するかきちんと日本語で説明を追記してください。
aaaaaaaa

2018/08/06 10:00

ご指摘ありがとうございます。ソースを整形しました。
guest

回答2

0

ベストアンサー

なんか難しく考えすぎではないですかね。
提示のコードの意図するところが読み取れません。やり直ししたほうがいいです。

今BCMATH関数が使える環境が手元にないので、BCMATH関数を使わないで書くと、こんな感じ。
キモはwhileの中の3行だけです。

php

1<?php 2 3 $target = "777777777777777777"; 4 $result = 0; 5 $radix = 8; 6 7 $a = preg_split("//u", $target, -1, PREG_SPLIT_NO_EMPTY); 8 9 # 先頭の文字から1つずつ、計算結果を×8して数値を加算する、を繰り返す 10 while(count($a) > 0){ 11 $c = array_shift($a); 12 $result *= $radix; 13 $result += intval($c); 14 } 15 16 print $result;  #18014398509481983 17 18?>

64bit環境なら桁あふれを起こしません。
掛け算のところをbcmulに、足し算のところをbcaddに置き換えればBCMATH環境でも動くと思います。

投稿2018/08/03 11:13

hope_mucci

総合スコア4447

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

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

0

とりあえずPHPには任意の基数に変換する関数があります。
echo base_convert(777777777777777777, 8, 10);
この実行結果は18014398509481983です。
またIntegerに収まらない値はfloatで返すoctdec関数もint型で18014398509481983を返してくれます。

投稿2018/08/03 10:22

namda

総合スコア705

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問