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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

3回答

1258閲覧

同じ式を表しているのに書き方を変えると数値が違うものになってしまいます

ko20vonobird

総合スコア50

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2017/03/29 08:21

###前提・実現したいこと
紙に書いた数式をコード上で書き起こし、正確な値を得ることです。

###発生している問題・エラーメッセージ
エラーメッセージはありません。
数式には交換法則がありますが、それに従って違った書き方の同じ数式を書くと、中身は同じはずなのに全く違った値になります。
また、正しい値(補足参照)が得られません。
下記のc1rの数式がそれです。

###該当のソースコード

Java

1k1a = (winH * 253) / (winW * 246);//k = 項 2 k2a = winW / 4; 3 k3a = -1.0f; 4 k4a = ((winW * 0.8105067459f) / 4); 5 k5a = winW * 0.1473648629f; 6 k6a = winH / 8; 7 k7a = ((winH * 5) / 6); 8 k8a = ((winH * 253) / 328); 9 bsa = Math.abs((k1a * k2a) + (k3a * (k4a + k5a - k6a)) + k7a - k8a);//一つ目の書き方 10 c1r = (float)(bsa / (Math.sqrt(Math.pow(k1a, 2) + Math.pow(k3a, 2)))); 11 c1r = (float)((Math.abs(((winH * winW * 253) / (winW * 4 * 246)) + (-1) * (((winW * 0.8105067459f) / 4) + (winW * 0.1473648629f) - (winH / 8)) + ((winH * 5) / 6) - ((winH * 253) / 328))) / (Math.sqrt(Math.pow(((winH * 253) / (winW * 246)), 2) + Math.pow(-1, 2))));//二つ目の書き方

###試したこと
交換法則に従い順番を変えてみました。

###補足
このc1rは円の半径に用いていて、上記のコードには載せていない直線と接するかで正しい値が得られているかを判断しています。

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

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

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

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

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

guest

回答3

0

ベストアンサー

winHwinWが整数だと、k2a = winW / 4などでバシバシ切り捨てられてしまうので、正しい値が出ません。とりあえず、k2a = winW / 4.0というように浮動小数の計算に持ち込んでおきましょう。

(もちろん、寸分たがわぬ値を出したいというのであれば誤差の吟味も必要ですが、整数で切り捨てが発生してしまえば、それ以上に大問題です)

投稿2017/03/29 08:53

maisumakun

総合スコア145184

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

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

ko20vonobird

2017/03/29 09:01

他の方にも同じような回答があったのですが、winH=winH*1.0などすることで対応できますか?
maisumakun

2017/03/29 09:04

winHの変数の型が整数であれば、全く無意味です。
ko20vonobird

2017/03/29 09:06

なるほど、わかりました。
swordone

2017/03/29 09:15

型が整数型ならコンパイルエラーだし、浮動小数点型なら意味ないですね。
guest

0

winHやwinWが整数なら、すべての前提が崩れます。
整数同士の除算は小数切捨てなので、交換法則はおろか、最初のk1a*k2aに当たる計算も必ずしも等しくならなくなります。

投稿2017/03/29 08:53

swordone

総合スコア20651

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

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

ko20vonobird

2017/03/29 09:00

こんにちは。 ということは、winH=winH*1.0などして少数に直せばよいでしょうか?
ko20vonobird

2017/03/29 09:09

他の方に教えていただき、ダメだということが分かりました。
guest

0

プリミティブ型(float, double等)を使っているため計算に誤差が生じています。

全ての変数をBigDecimal型で扱い計算をすれば正しい値が得られます。

詳細は公式のJavaDocを参照された方が良いですが、四則演算をするにはザックリ以下のような感じです。
加算:BigDecimal#add(BigDecimal)
減産:BigDecimal#subtract(BigDecimal)
乗算:BigDecimal#multiply(BigDecimal)
除算: BigDecimal#divide(BigDecimal)

プリミティブ型での計算で誤差が生じる理由をかくに言葉足らずになるかと思うので、ご自身で検索された方が良いかと思います。

  • java
  • プリミティブ
  • 誤差

投稿2017/03/29 08:46

編集2017/03/29 09:02
type23

総合スコア18

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

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

ko20vonobird

2017/03/29 09:03

初めて聞きました、ありがとうございます。取り敢えず調べます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問