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

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

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

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

Q&A

解決済

2回答

2112閲覧

10進数の数値を変換すると容量が足らなくなる理由

aaaaaaaa

総合スコア501

PHP

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

0グッド

0クリップ

投稿2017/04/05 10:44

php

1 2$sho = 1; 3$zyusinsu[0] = 15;//10進数の15 4$henkanSitai_nsinsu = 8;//15を8進数にするときに利用する 5 6 for($i=0;$sho!==0;$i++) { 7 8 //まず10進数の$zyusinsu[0]を、変換したいn進数($henkanSitai_nsinsu)で割る。割った数値は、商を意味する$shoに代入。小数点がある場合は、正規表現で小数点以下を削除。小数点以下を削除した値も$shoに代入。 9 //希望のn進数の数値を求めるには、余が必要なので余も計算しておく。余は、その数値の下一桁目から求めることになっている。一つずつ求める処理なので、それぞれの値は、$henkango_nsinsuに代入される。 10 11 12 13 //導き出したいn進数の商を求める。 14 //なら、なぜ商($sho)も求めるのかというと、この"再度別のn進数に変換する"という計算式の終わりの印に必要だからである。この場合の印は、$shoが「0」になることだ。 15 $sho = $zyusinsu[0] / $henkanSitai_nsinsu; 16 17 //fatalerror allowed memory size of...bytes exhaustedがでたのでメモリを増やしてみたところ、今度は画面が真っ白に。 18 ini_set("memory_limit","150MB"); 19 //$shoに小数点以下の数字があればそれを削除する。小数点を削除した数値をさらに$henkanSitai_nsinsuで割っていく。 20 $syosutenSakuzyo = "/^(\d+)(\.\d+)*/";// 21 //$shoに小数点があれば、小数点以下を削除。削除後の$shoの型はstringである。 22 $sho = preg_replace($syosutenSakuzyo,"$1",$sho);//この行でエラーが出ている模様。 23 24 25 //下一桁目から変換したいn進数を求める。一桁ずつ配列に保存していく。 26 //例 $zyusinsu[0](15)、$henkanSitai_nsinsuが8進数にしたいので8である。15/8は、1...7なので$henkango_nsinsu[]配列には7が入る。 27 //※「$henkango_nsinsu[] = $sho % $henkanSitai_nsinsu;」とすると、下二桁目から求めることになってしまうので(1/8=0...8)、"最初に計算を行うときのみ"割られる値は、$zyusinsu[0]だ。 28 // 二回目以降の計算で、$zyusinsu[0]から$shoに変更しなくてはならない。 29 30 if($i === 0) { 31 $henkango_nsinsu[] = $zyusinsu[0] % $henkanSitai_nsinsu; 32 } else { 33 $henkango_nsinsu[] = $sho % $henkanSitai_nsinsu; 34 } 35 }

$zyusinsu[0]には、10進数の値が代入されており、$henkanSitai_nsinsuには、4進数であったり8進数などの進数を意味する値が入っており、この値で$zyusinsu[0]を割ることで$henkanSitai_nsinsuで指定したn進数に($henkanSitai_nsinsuが2なら4進数に、8なら8進数に)変換する、という処理ですが、実行すると

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 36 bytes) in C:\xampp\htdocs\Decimal\lib\test.php on line 39

この39行目は、$sho = preg_replace($syosutenSakuzyo,"$1",$sho);にあたります。なので、ini_set("memory_limit","150MB"); で容量を増やしてみたのですが、今度は真っ白な画面が表示されるようになりました。
150MBにしたのは、134MBでは足りない、というエラー文言を目にしたからです。因みにphpinfo()してmemory_limitを調べるとmemory_limit 128M 128M でした。

なぜ、容量が足らなくなったのでしょうか。どうすると正常に処理されるのでしょうか。

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

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

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

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

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

guest

回答2

0

ベストアンサー

PHP: intdiv - Manual
https://3v4l.org/NFb5o

浮動小数点で得られた結果を整数化するためにわざわざpreg系関数なんて使わずに、
intdiv()使いましょうよ。

php7でないならば、
まず先に余りを求めてから、割る対象の数字から先に余りを引いたものを、
割ります。
https://3v4l.org/o4Pl0

PHP

1<?php 2 3$zyusinsu[0] = 15; 4$henkanSitai_nsinsu = 8; 5$sho = ($zyusinsu[0] - ($zyusinsu[0] % $henkanSitai_nsinsu)) / $henkanSitai_nsinsu; 6var_dump($sho);

結果

int(1)

投稿2017/04/05 10:57

編集2017/04/05 11:08
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

aaaaaaaa

2017/04/14 10:33 編集

ご回答有難うございます。 利用しているphpは、5.5.9ですので回答文の計算式を利用することで、``$sho = preg_replace($syosutenSakuzyo,"$1",$sho);``から発生していたfatalerrorが無くなりなした。 しかし、今度は、``$henkango_nsinsu[] = $sho % $henkanSitai_nsinsu;``からFatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 36 bytes) が出てしまいました。 他の回答からすると配列に情報を入れ過ぎた、ということになりますが、処理上15/8、1/8の二回しか計算しないので2回代入されたのですが、なぜメモリが足らなくなってしまったのでしょうか。
退会済みユーザー

退会済みユーザー

2017/04/17 01:45

$henkango_nsinsu[] などと配列で持たなくても良いように、文字列に連結したら良いと思います。結果として最終的に出力するときは文字列でしょうから、メモリをガッツリ使う配列で最初の桁から現在の桁までのデータをきっちり配列で持っても使いみちがないし、配列で持ってしまうことでメモリが不足するなら結果用文字列変数を設けて末尾に連結したら良いです。それとも、配列で必ず処理を完結しなければならない特殊な事情があるのでしょうか。
aaaaaaaa

2017/04/18 10:39

ご返答有難うございます。 連結するときに使用するのは、複合代入演算子「.=」でしょうか。それともほかに何か方法などは、あるのでしょうか。
guest

0

結論を言うと、メモリが足りないのはfor文で配列に値を入れ過ぎです。

メモリはねー、データを入れる箱のようなものだよー

例えば
メモリという箱に空きスペースが5つあるとします。
1つのスペースに1つの変数がいれられます。

php

1$x=1; 2echo $x; 3$y=2; 4echo $y;

これを実行すると、変数が2つ宣言されているので、メモリの空きが3つになります。
メモリに異常はないため、エラーは出ません。

php

1$x = array(1,2,3,4); 2echo $x; 3$y = array(5,6,7,8); 4echo $y;

配列の場合はどうでしょうー、これは8つの箱を消費します。
メモリは5つまでなのでエラーですねー。

では解決するには?

php

1$x = array(1,2,3,4); 2echo $x; 3$x = 0; 4$y = array(5,6,7,8); 5echo $y;

こんな風に使い終わった配列にリセットをかけましょう~
for文の最後とかに初期化するような(上記だと$x=0;)コードを入れれば解決するかも!
まぁ、下記みたいに一回のfor内でメモリ越えたら意味ないけど・・・

php

1$x = array(1,2,3,4,5,6,7); // 7つなのでこの時点でメモリー不足w

投稿2017/04/06 05:15

ImSleep

総合スコア39

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

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

aaaaaaaa

2017/04/14 10:33

ご回答有難うございます。 配列に代入したことによってメモリが逼迫したわけなのですね。 for文の途中で、Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 36 bytes)が出てしまいます。 for文を脱するまでは、配列を上書きしたくないのですが、このような条件でエラーを防ぐにはどうすべきなのでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問