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

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

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

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

Q&A

解決済

2回答

5444閲覧

PHP: BCMath任意精度数学関数のbcadd()の動きがよく分かりません

ID_7UGzV8hCHGs5

総合スコア58

PHP

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

0グッド

0クリップ

投稿2018/01/30 04:54

編集2018/01/30 05:12

わからないこと&解決したいこと

小数第10位まで正確に計算したくて、BCMath関数を使用しておりました。
(加算、減算、割り算、掛け算 全て使用)

ふと、本当に正確なのか気になって
シンプルな値でBCMathの動きをテストしました。

すると、
bcadd()にて下記2つの数値を足すと結果が0になってしまいました。
数値1: 0.0000000100
数値2: 0.0000000200
合計: 0.0000000300 //この値が欲しい。

※ちなみに、通常の"+"を使用して上記の加算を行ったところ問題無く結果が得られました。
ただそれは一旦置いておき、なぜbcadd()だと上手くいかないのかとても疑問に思い夜も眠れません。

試したコード

▼ "bcadd()"を使った加算 その1 $n1 = 0.0000000100; $n2 = 0.0000000200; $sum = bcadd($n1, $n2, 10); echo sprintf('%.10f', $sum).PHP_EOL; //出力結果: 0.0000000000 //0になってしまった。 ▼ "bcadd()"を使った加算 その2 $n1 = 1.0000000100; //1を足してみた $n2 = 1.0000000200; //1を足してみた $sum = bcadd($n1, $n2, 10); echo sprintf('%.10f', $sum).PHP_EOL; //出力結果: 2.0000000300 //正確に計算できている。。なぜなんだろう ▼ "+" を使った加算 $n1 = 0.0000000100; $n2 = 0.0000000100; $sum = $n1 + $n2; echo sprintf('%.10f', $sum).PHP_EOL; //出力結果: 0.0000000200 //正確に計算できている

お願い

加算にはbcadd()ではなく通常の"+"をつかうべきなんでしょうか。
皆さんどうされているのでしょうか。
よろしくお願い致します。

追加テストコード

(上記に書いたように)初めに1を足しておくと正確な計算が出来ているようなので、
1ではなくもう少し小さい値にしたらどうなるのかと気になり、テストしてみました。

結果概要:
初めに足しておく値が少なくとも「0.0001」より小さくなると、計算が上手くいかないという事実が分かりました。
この結果が何を意味しているのかは全く分かりませんが、とりあえず報告致します。

▼0.1を足しておく $n1 = 0.1000000100; $n2 = 0.1000000200; $sum = bcadd($n1, $n2, 10); echo sprintf('%.10f', $sum).PHP_EOL; //0.2000000300 //正確 ▼0.01を足しておく $n1 = 0.0100000100; $n2 = 0.0100000200; $sum = bcadd($n1, $n2, 10); echo sprintf('%.10f', $sum).PHP_EOL; //0.0200000300 //正確 ▼0.001を足しておく $n1 = 0.0010000100; $n2 = 0.0010000200; $sum = bcadd($n1, $n2, 10); echo sprintf('%.10f', $sum).PHP_EOL; //0.0020000300 //正確 ▼0.0001を足しておく $n1 = 0.0001000100; $n2 = 0.0001000200; $sum = bcadd($n1, $n2, 10); echo sprintf('%.10f', $sum).PHP_EOL; //0.0002000300 //正確 ▼0.00001を足しておく $n1 = 0.0000100100; $n2 = 0.0000100200; $sum = bcadd($n1, $n2, 10); echo sprintf('%.10f', $sum).PHP_EOL; //0.0000000000 //0になった。。

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

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

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

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

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

guest

回答2

0

bcadd の引数にはいずれも文字列を指定してください。

php

1<?php 2$n1 = '0.0000000100'; 3$n2 = '0.0000000200'; 4$sum = bcadd($n1, $n2, 10); 5echo $sum.PHP_EOL; 6

bash

1$ php a1.php 20.0000000300 3

投稿2018/01/30 05:14

hotta

総合スコア1613

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

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

ID_7UGzV8hCHGs5

2018/01/30 05:44

hottaさん 回答頂きありがとうございます。 頂いたコードで正確な値が出る事を確認致しました。 非常に助かりました。 お礼申し上げます。
guest

0

ベストアンサー

bcaddに渡すべき引数は文字列です(リファレンス)。数値を渡してしまうと、bcmathに渡る前に意図しない変換が入ってしまい、うまく動かなくなります。

文字列引数で動かしてみた例

投稿2018/01/30 05:14

maisumakun

総合スコア145183

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

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

ID_7UGzV8hCHGs5

2018/01/30 05:41

maisumakunさん ありがとうございました。 文字列にしたところ正しく動くことを確認しました。 問題の解決の他に、「動かしてみた例」のような便利なサイトを知る事が出来きてうれしく思います。 お礼申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問