胃息肉是什么引起的| 流清水鼻涕是什么感冒| 红细胞数目偏高是什么意思| 病灶什么意思| 痔疮是什么样的图片| 大姨妈一个月来两次是什么原因| 阿胶什么人不能吃| 玉米是什么植物| 窝沟封闭什么意思| 七宗罪分别是什么| 飞短流长是什么意思| 什么的目光| 追求是什么意思| 舌苔发白什么原因| 白鹭吃什么| 地素女装属于什么档次| 做激光近视眼手术有什么危害| 挖矿是什么| 银屑病为什么会自愈| 骨质增生什么意思| 社保卡是什么样的图片| 吃什么食物治便秘| 腱鞘炎看什么科| 晚上尿床是什么原因| 羊癫疯是什么引起的| 快走对身体有什么好处| 芹菜炒什么| 产后抑郁症有什么表现症状| 芽轴发育成什么| 转氨酶高说明什么| 94年什么命| 头皮疼是什么原因引起的| 鹿晗有什么歌| 女人的第二张脸是什么| 为什么睡觉会打呼| 吃茄子对身体有什么好处| 火拼是什么意思| 孙笑川是什么梗| 脾是干什么用的| 西红柿生吃有什么好处| 为什么喝酒| 槟榔什么味道| 为什么会长小肉粒| 人模狗样是什么生肖| 松鼠尾巴有什么作用| 隔离霜和粉底液有什么区别| nit是什么意思| 肚子疼吃什么| 吹泡泡什么意思| 石榴红是什么颜色| 幼犬可以吃什么| 射精太快吃什么好| 桓是什么意思| 彩超无回声是什么意思| 梦见对象出轨什么征兆| 吃什么可以快速排便| 挑染什么颜色好看| 海水倒灌是什么意思| 腿疼膝盖疼是什么原因| 黑裙子配什么鞋子| 花生碎能做什么食物吃| 6.26是什么星座| 81年属鸡是什么命| 脚背麻木是什么原因| 后背长痘是什么原因| 土克水是什么意思| 栀子有什么作用与功效| 华为什么手机好| 公斤和斤有什么区别| 蛋白尿是什么意思| 心脏房颤是什么意思| 缺钾吃什么药| 甘的部首是什么| 低压48有什么危险| 6月22日是什么星座| 永垂不朽什么意思| 秋天是什么时候| 晚上夜尿多是什么原因| 家庭养什么狗最干净| 眼睛浮肿是什么原因引起的| 女人下身干燥无水是什么原因| hr什么意思| 7是什么意思| 普门品是什么意思| 农历9月11日是什么星座| 7月25日什么星座| 刚字五行属什么| 什么什么万分| 便秘缺什么维生素| 知了猴是什么东西| 正月十八是什么星座| 清华大学书记什么级别| 珩是什么意思| 石男是什么意思| 春雨绵绵是什么生肖| 什么是碧玺| miu是什么意思| chihiro是什么意思| 7月29是什么星座| 黄痰是什么原因造成的| 梦见自己搬家是什么意思| 含五行属什么| 为什么明星都不戴黄金| 风景旧曾谙是什么意思| 血气是什么意思| 为什么老是想睡觉| 尿红细胞高是什么原因| 八月六号是什么星座| 这个季节适合种什么蔬菜| 结婚长明灯有什么讲究| 胃不舒服挂什么科| 一个合一个页读什么| 胃有息肉的症状是什么| 输卵管堵塞有什么样症状| 98年虎是什么命| 女生考什么证书最实用| 粘假牙用什么胶| 看病人送什么水果| 腹部彩超能查出什么| 女人出黄汗是什么原因| 孕妇吃鸡蛋对胎儿有什么好处| 口苦吃什么药好| 疑似是什么意思| 膝盖骨质增生用什么药效果好| 公检法是什么| 复健是什么意思| 男人肾虚吃什么最补| 2003年是什么命| 喝酒脸红是什么原因| 左下腹疼痛是什么原因| 经期吃什么水果比较好| 黄芪入什么经| 书字五行属什么的| 甲鱼和什么一起炖最好| tfcc是什么| 宿便什么意思| 西红柿吃多了有什么坏处| 什么是角阀| 脱肛和痔疮有什么区别| 老爹是什么意思| 胃气上逆吃什么中成药| 肺气不足吃什么药| 菜花炒什么好吃| 闷骚是什么意思| 降火吃什么药| 嘴唇周围长痘痘是什么原因| 胎儿偏小是什么原因| 强直性脊柱炎吃什么药| 为什么人一瘦就会漂亮| 抽烟手抖是什么原因| 玄青色是什么颜色| 小腹胀痛男性什么原因| 慢性咽炎挂什么科| 眼睛干涩用什么药| 艾滋病简称什么| 玉髓什么颜色最贵| 2005属什么| 日单是什么意思| 脑血栓前兆是什么症状表现| 血清铁蛋白是检查什么| 冬至广东吃什么| 圣诞节适合送什么礼物| 亮晶晶的什么| 8月10号是什么星座| 阳刃是什么意思| 小沈阳属什么生肖| 大名是什么意思| 子宫肌瘤有什么症状| 扩胸运动有什么好处| 老人越来越瘦是什么原因| 什么是鸡尾酒| 什么是西米| 燕麦长什么样子图片| 碱性食物对身体有什么好处| 胸腔疼挂什么科| 异食癖是什么意思| 属狗女和什么属相最配| 今期难过美人关是什么生肖| 报恩是什么意思| 什么是潮汐车道| 润六月是什么意思| 滴虫病女性有什么症状| 什么油适合炒菜| 甲醛超标有什么危害| ne医学上是什么意思| forever21是什么牌子| 渗透压是什么| 与世无争是什么意思| 激素六项挂什么科| 紫色和蓝色混合是什么颜色| 符号代表什么| 降血脂吃什么药| 肋骨断了是什么感觉| 5月2号是什么星座| 黄龙玉产地在什么地方| 惊弓之鸟什么意思| 喜欢一个人会有什么表现| 女人吃什么补气血| 西游记什么朝代写的| 什么品牌的假发好| 春什么秋什么的成语| 中国海警是什么编制| 当归不能和什么一起吃| 殚精竭虑是什么意思| 心悸吃什么药效果好| 火红的太阳像什么| 外阴白斑挂什么科| 正常白带是什么样的| 肌电图挂什么科| 单核细胞高是什么意思| 图灵测试是什么| 甲状腺炎有什么症状表现| 心室预激是什么意思| 7月28号是什么星座| 什么是平舌音| 戾气什么意思| 肚子上长毛是什么原因| 综合内科是看什么病| 经常晕倒是什么原因引起的| 元旦唱什么歌| 狗哭了代表什么预兆| 李时珍的皮是什么意思| 手臂上长痣代表什么| 背上长毛是什么原因引起的| 扁桃体发炎挂什么科| 粉色是什么颜色配成的| 征文是什么| 无花果什么品种最好吃| 全套半套什么意思| dc是什么| 什么属相不能住西户| 凤鸾是什么意思| 粽子叶是什么植物的叶子| 口腔出血是什么原因| 丝状疣长什么样| 吃什么食物对心脏有好处| 弯是什么意思| 支气管舒张试验阳性是什么意思| 往生咒是什么意思| 什么是心脏造影| 四月十五日是什么日子| 牢固的近义词是什么| 什么人容易得小脑萎缩| wbc是什么意思医学| 经血是什么血| 甘蓝是什么| 鹦鹉吃什么食物最好| 骨外科是看什么病的| 梦见很多蜜蜂是什么意思| 脚肿是什么原因造成的| 垚字五行属什么| 鸡眼用什么药好| 桃子又什么又什么填空| 神经衰弱吃什么中成药| 幸灾乐祸是什么意思| 多吃火龙果有什么好处和坏处| 安抚奶嘴什么时候开始用| 外感是什么意思| 入赘是什么意思| 前列腺在人体什么位置| 什么病不能吃虾| 力所能及什么意思| 农历六月十四是什么星座| 肛门湿疹用什么药膏最有效| 百度コンテンツにスキップ

发条是什么意思

出典: フリー教科書『ウィキブックス(Wikibooks)』

式と演算子

[編集]
百度   我国国土面积辽阔、地形与气候多样,崎岖山路、泥泞洼地、冰霜雪道等极端路况时不时就会出现在卡车用户的运输过程中。

プログラミングにおける式(Expression)は、値や演算子、関数呼び出し、変数などから構成される計算を表す文法構造です。式はプログラム内で評価され、結果の値を生成します。

演算子(Operator)は、式内で値や変数を操作するための記号またはキーワードです。演算子には算術演算子(加算、減算など)、比較演算子(等しい、大なり、小なりなど)、論理演算子(AND、ORなど)、代入演算子(変数に値を代入する演算子)などがあります。演算子は一般的に、式内で値を組み合わせて新しい値を生成するために使用されます。

例えば、以下のような式があります:

a + b * c

この式は、変数 abc の値を使用して、乗算(*)と加算(+)の演算を行います。これにより、新しい値が生成されます。

Javaにおける式と演算子

[編集]

Javaにおける式(Expression)は、値、変数、演算子、メソッド呼び出し、またはこれらの組み合わせから構成されるプログラム内の計算を表す文法要素です。式はプログラム内で評価され、結果の値を生成します。

Javaの演算子(Operator)は、式内で値や変数を操作するための特殊な記号またはキーワードです。

Javaの演算子は多岐にわたり、主な種類には以下のようなものがあります:

  1. 算術演算子(Arithmetic Operators): 加算(+)、減算(-)、乗算(*)、除算(/)、剰余(%)など、数値データ型の間で算術演算を実行するための演算子です。
  2. 比較演算子(Comparison Operators): 等しい(==)、等しくない(!=)、大なり(>)、小なり(<)、大なりイコール(>=)、小なりイコール(<=)など、値や式の比較を行うための演算子です。結果は真偽値(trueまたはfalse)となります。
  3. 論理演算子(Logical Operators): 論理積(AND:&&)、論理和(OR:||)、否定(NOT:!)など、真偽値を操作するための演算子です。
  4. ビット演算子(Bitwise operators): 論理積(AND:&)、論理和(OR:|)、排他的論理和(XOR:^)、否定(NOT:~)などの操作を提供し、ビット単位の操作により効率的なデータ処理やビットマスクの作成が可能です。
  5. 代入演算子(Assignment Operators): 代入(=)、加算代入(+=)、減算代入(-=)、乗算代入(*=)など、変数に値を代入するための演算子です。
  6. その他の演算子(Other Operators): インクリメント(++)、デクリメント(--)、条件演算子(条件式 ? 結果1 : 結果2)、ビット演算子(ビット単位の論理演算を行う演算子)など、その他の種類の演算子があります。

これらの演算子を使用して、Javaプログラム内で様々な計算や操作を行うことができます。

算術演算子

[編集]

Javaにおける算術演算子は、基本的な数値計算を行うための演算子を指します。 Javaでは、整数型と浮動小数点型のデータを扱うための算術演算子が提供されています。

主な算術演算子には以下が含まれます:

  1. 加算(Addition)
    int sum1 = 5 + 3; // 整数の加算、sum1には8が代入される
    double sum2 = 5.5 + 3.2; // 浮動小数点数の加算、sum2には8.7が代入される
    
  2. 減算(Subtraction)
    int difference1 = 10 - 4; // 整数の減算、difference1には6が代入される
    double difference2 = 10.5 - 4.2; // 浮動小数点数の減算、difference2には6.3が代入される
    
  3. 乗算(Multiplication)
    int product1 = 6 * 2; // 整数の乗算、product1には12が代入される
    double product2 = 3.5 * 2.0; // 浮動小数点数の乗算、product2には7.0が代入される
    
  4. 除算(Division)
    double quotient1 = 10.0 / 3.0; // 浮動小数点数の除算、quotient1には3.3333...が代入される
    double quotient2 = 10 / 3.0; // 整数と浮動小数点数の除算、quotient2には3.3333...が代入される
    
  5. 剰余(Modulus)
    int remainder1 = 10 % 3; // 整数の剰余、remainder1には1が代入される
    double remainder2 = 10.5 % 3.0; // 浮動小数点数の剰余、remainder2には1.5が代入される
    

Javaの算術演算は、整数型と浮動小数点型の両方で動作し、適切な結果を返します。 プログラマは、演算に使用される数値の型を適切に選択する必要があります。

多様な算術演算子

[編集]
/**
 * 算術演算子の例
 */
public class Main {

    /**
     * メインメソッド。プログラムのエントリーポイント。
     * 
     * @param args コマンドライン引数
     */
    public static void main(String[] args) {
        int a = 10;
        int b = 3;
        
        System.out.println(a + " + " + b + " = " + (a + b));
        System.out.println(a + " - " + b + " = " + (a - b));
        System.out.println(a + " * " + b + " = " + (a * b));
        System.out.println(a + " / " + b + " = " + (a / b));
        System.out.println(a + " % " + b + " = " + (a % b));

        a = Integer.MAX_VALUE;
        b = 1;
        System.out.println(a + " + " + b + " = " + (a + b) + "\t// オーバーフロー!");

        // ゼロ除算:
        a = 42;
        b = 0;
        try {
            System.out.print(a + " / " + b + " = ");
            System.out.println(a / b);
        } catch (ArithmeticException e) {
            System.out.println("例外捕捉:" + e);
        }
        
        // ゼロ除算:
        try {
            System.out.print(a + " % " + b + " = ");
            System.out.println(a % b);
        } catch (ArithmeticException e) {
            System.out.println("例外捕捉:" + e);
        }
        
        // double型の算術演算
        double x = 10.5;
        double y = 3.2;
        System.out.println(x + " + " + y + " = " + (x + y));
        System.out.println(x + " - " + y + " = " + (x - y));
        System.out.println(x + " * " + y + " = " + (x * y));
        System.out.println(x + " / " + y + " = " + (x / y));
        System.out.println(x + " % " + y + " = " + (x % y));

        y = 0.0;
        System.out.println(x + " / " + y + " = " + (x / y));

        x = 0.0;
        System.out.println(x + " / " + y + " = " + (x / y));
    }
}
実行結果
10 + 3 = 13
10 - 3 = 7
10 * 3 = 30
10 / 3 = 3
10 % 3 = 1
2147483647 + 1 = -2147483648	// オーバーフロー!
42 / 0 = 例外捕捉:java.lang.ArithmeticException: / by zero
42 % 0 = 例外捕捉:java.lang.ArithmeticException: / by zero
10.5 + 3.2 = 13.7
10.5 - 3.2 = 7.3
10.5 * 3.2 = 33.6
10.5 / 3.2 = 3.28125
10.5 % 3.2 = 0.8999999999999995
10.5 / 0.0 = Infinity 
0.0 / 0.0 = NaN

InfinityとNaN

[編集]

JavaのInfinityとNaNは、浮動小数点数の特殊な値であり、IEEE 754規格に基づいて定義されています。以下に、それぞれの意味と特性について説明します。

JavaのInfinityとNaNは、浮動小数点数の計算において特殊な値として使用されます。これらの値は、次のような場面で発生します。

  1. Infinity(無限大):
    • 無限大は、有限の数値を0.0で割った場合や、オーバーフローが発生した場合に発生します。
    • 例えば、double result = 5.0 / 0.0;のような式を評価すると、resultの値は無限大になります。
    • 無限大は、有限の数値よりも大きいことが特性として挙げられます。
    • Double.POSITIVE_INFINITYの定数は(正の)無限大を表します。
    • IEEE 754規格では、無限大は指数部が符号が+、最大値でかつ仮数部が0の状態で表されます。
  2. -Infinity(負の無限大):
    • 負の無限大、有限の負の数値を0.0で割った場合や、オーバーフローが発生した場合に発生します。
    • 例えば、double result = 5.0 / -0.0;のような式を評価すると、resultの値は負の無限大になります。
    • 負の無限大は、有限の数値よりも小さいことが特性として挙げられます。
    • Double.NEGATIVE_INFINITYの定数は、負の無限大を表します。
    • IEEE 754規格では、負の無限大は指数部が符号が+、最大値でかつ仮数部が0の状態で表されます。
  3. NaN(非数):
    • NaNは、0を0で割った場合や、0.0を0.0で割った場合、あるいは数学的に不正な演算が行われた場合に発生します。
    • 例えば、double result = Math.sqrt(-1);のような式を評価すると、resultの値はNaNになります。
    • NaNは、数値としての意味を持たないことを示します。
    • Double.NaNという定数があり、これはNaNを表します。
    • NaNは、どの数値とも等しくないため、NaNとの比較は常にfalseになります。
    • IEEE 754規格では、NaNは指数部が最大値でかつ仮数部が0でない状態で表されます。

isNaN()とisFinite()メソッド:

  • Javaでは、DoubleクラスやFloatクラスには、NaNやInfinityを判定するためのメソッドが用意されています。
  • isNaN()メソッドは、引数がNaNかどうかを判定します。NaNの場合はtrueを返し、それ以外の場合はfalseを返します。
  • isFinite()メソッドは、引数が有限の数かどうかを判定します。InfinityやNaNの場合はfalseを返し、それ以外の場合はtrueを返します。

IEEE 754規格に基づいて定義されたこれらの特殊な値は、浮動小数点数の算術演算においてエラー処理や特殊な状況を処理するために使用されます。これらの特性を理解することは、正確な数値計算を行う上で重要です。

-0.0

[編集]

-0.0(マイナスゼロ)は、浮動小数点数の一部で、通常のゼロとは異なる概念です。IEEE 754規格では、ゼロを表現する方法として、符号付きゼロ(+0.0および-0.0)が導入されています。

  • +0.0(プラスゼロ): すべてのビットが0で、符号ビットが0。
  • -0.0(マイナスゼロ): すべてのビットが0で、符号ビットが1。

この区別は、通常の算術演算では影響を与えませんが、一部の特殊な状況で重要になります。例えば、次のような場面で符号つきゼロが役立ちます。

  1. ゼロで割った場合:
    • 1.0 / +0.0 は正の無限大になります。
    • 1.0 / -0.0 は負の無限大になります。
  2. 符号を保持する場合:
    • 符号つきゼロは、正確な結果を保持するために使用されます。例えば、正の数から負の数を引くときなどに、結果の符号を正確に反映するために使われます。

JavaのDoubleとFloatのデータ型では、+0.0と-0.0は異なる値として区別されます。これは、JavaがIEEE 754規格に従っているためです。例えば、以下のようなコードを実行すると、+0.0と-0.0が等しいかどうかを確認できます。

System.out.println(0.0 == -0.0); // true
System.out.println(Double.compare(0.0, -0.0)); // 1
System.out.println(Double.compare(0.0, 0.0)); // 0
System.out.println(Double.compare(-0.0, 0.0)); // -1
このコードでは、==演算子によって0.0と-0.0が等しいかどうかを比較しています。
Double.compareメソッドによって比較すると、ゼロの符号の違いを考慮します。

Double.compare() は、Java プログラミング言語において、2 つの double 値を比較するための静的メソッドです。このメソッドは、次のような形式で使用されます:

public static int compare(double d1, double d2)

Double.compare() メソッドは、以下のルールに従って比較を行います。

  • もし d1d2 より小さい場合、負の値が返されます。
  • もし d1d2 より大きい場合、正の値が返されます。
  • もし d1d2 と等しい場合、0 が返されます。

算術演算の注意事項

[編集]

桁あふれ

[編集]

整数演算の桁あふれ

[編集]

整数演算の桁あふれ(オーバーフロー)は、整数の演算結果がそのデータ型で表現可能な範囲を超える場合に発生します。Javaの整数型には、それぞれの範囲が定義されています。以下に、主な整数型とその範囲を示します。

  1. byte: -128 から 127
  2. short: -32,768 から 32,767
  3. int: -2,147,483,648 から 2,147,483,647
  4. long: -9,223,372,036,854,775,808 から 9,223,372,036,854,775,807

たとえば、int型でのオーバーフローが発生する状況を考えてみましょう。以下のコードでは、整数の最大値に1を加えようとしています。

int maxValue = Integer.MAX_VALUE;
int overflow = maxValue + 1;
System.out.println("Overflow: " + overflow);

このコードを実行すると、overflow 変数は -2147483648 になります。これは、Integer.MAX_VALUE で表現される最大値に1を加えることで、オーバーフローが発生し、最小値(Integer.MIN_VALUE)に戻るためです。

同様に、他の整数型でも同様の挙動が発生します。オーバーフローを防ぐためには、適切な範囲内での演算を行うか、オーバーフローが発生する可能性がある場合には適切に処理する必要があります。

Math.addExactと、そのファミリー
[編集]

Javaでは、整数演算でオーバーフローを生じても例外は上がりません。 例外をあげオーバーフローを捕捉するために、Math.addExactと、そのファミリーが用意されています。

Math.addExact() メソッドは、Java 8 で追加された整数演算時のオーバーフローを検出するためのメソッドの一部です。このメソッドは、整数型の加算を行い、結果がそのデータ型で表現可能な範囲を超えた場合に ArithmeticException をスローします。

Math クラスには、他にもオーバーフローを検出するためのメソッドが用意されています。主なものには、次のようなものがあります:

  1. Math.addExact(int x, int y):整数値 xy を加算し、オーバーフローが発生した場合は ArithmeticException をスローします。
  2. Math.subtractExact(int x, int y):整数値 x から y を減算し、オーバーフローが発生した場合は ArithmeticException をスローします。
  3. Math.multiplyExact(int x, int y):整数値 xy を乗算し、オーバーフローが発生した場合は ArithmeticException をスローします。
  4. Math.incrementExact(int a):整数値 a をインクリメントし、オーバーフローが発生した場合は ArithmeticException をスローします。
  5. Math.decrementExact(int a):整数値 a をデクリメントし、オーバーフローが発生した場合は ArithmeticException をスローします。

これらのメソッドを使用することで、整数演算時にオーバーフローが発生した場合に、適切に例外を処理できます。

以下は、Math.addExact() メソッドを使用して整数値の加算を行い、オーバーフローが発生した場合に例外を処理する例です。

public class Main {
    public static void main(String[] args) {
        try {
            int result = Math.addExact(Integer.MAX_VALUE, 1);
            System.out.println("Result: " + result);
        } catch (ArithmeticException e) {
            System.out.println("Overflow occurred: " + e.getMessage());
        }
    }
}

このコードでは、Integer.MAX_VALUE に 1 を加算しようとしています。Math.addExact() メソッドは、この加算がオーバーフローを引き起こす可能性があるため、例外をスローします。try-catch ブロックを使用して、ArithmeticException をキャッチし、オーバーフローが発生したことを示すメッセージを出力しています。

浮動小数点演算の桁あふれ

[編集]

浮動小数点演算の桁あふれは、浮動小数点数を操作する際に、その値がデータ型で表現可能な範囲を超える場合に発生します。浮動小数点数は、指数部と仮数部から構成され、一定の精度を保ちつつ非常に大きな値や小さな値を表現するために使用されます。

Javaにおいて、浮動小数点数は主に以下の2つのデータ型で表現されます。

  1. float: 単精度浮動小数点数 (32ビット)
  2. double: 倍精度浮動小数点数 (64ビット)

これらのデータ型は、それぞれ一定の範囲と精度を持っていますが、非常に大きな値や小さな値に対しても表現可能です。

桁あふれは、浮動小数点演算の結果が、そのデータ型で表現可能な範囲を超える場合に発生します。これにより、計算結果が無限大や無限小に発散する場合や、精度が失われる場合があります。また、浮動小数点数の演算において、有効桁数を超えた部分が切り捨てられることも桁あふれの一形態です。

例えば、次のコードでは、倍精度浮動小数点数の最大値に1を加える操作を行っています。

double maxValue = Double.MAX_VALUE;
double overflow = maxValue + 1;
System.out.println("Overflow: " + overflow);

この場合、overflow 変数の値は Infinity になります。これは、最大値に1を加えた結果が倍精度浮動小数点数の表現可能な範囲を超えたため、桁あふれが発生したことを示しています。

浮動小数点数と誤差

[編集]

Javaの浮動小数点数における誤差は、主に2つの要因によって生じます。

  1. 有効桁数の制限: Javaの浮動小数点数は、IEEE 754標準に基づいて実装されています。float型は32ビットで、有効桁数は約7桁です。double型は64ビットで、有効桁数は約15桁です。そのため、非常に大きな数や非常に小さな数を表現する場合、精度の制限により誤差が生じます。たとえば、10進数で0.1をfloat型やdouble型で表現すると、厳密には0.1ではなく、近似的な値になります。
  2. 丸め誤差と演算誤差: 浮動小数点数の演算においては、丸め誤差や演算誤差が生じることがあります。これは、浮動小数点数を近似的に表現するための有限なビット数で演算を行うために生じるものです。特に、加算や減算、乗算、除算などの演算において、丸め誤差や演算誤差が生じることがあります。これにより、計算結果が厳密な値と異なる場合があります。

Javaの浮動小数点数における誤差を最小限に抑えるためには、次のような注意点があります。

計算の順序を適切に管理し、丸め誤差を最小限に抑える。

  • 必要に応じて、BigDecimalクラスを使用して高精度な計算を行う。
  • 数値計算ライブラリや専門家によって提供される特殊な数値計算手法を使用する。

これらの対策を講じることで、Javaの浮動小数点数による誤差を最小限に抑えることができます。

また、浮動小数点数の演算における丸め誤差や演算誤差を最小限に抑えるためには、以下のような注意点があります。

  1. 適切なデータ型を選択する: 浮動小数点数は精度を失う可能性があるため、必要な精度に合わせてfloat型またはdouble型を選択する必要があります。より高い精度が必要な場合はdouble型を使用しますが、その分メモリ使用量も大きくなります。
  2. 演算の順序を考慮する: 浮動小数点数の演算においては、演算の順序が結果に影響を与える場合があります。たとえば、加算や減算といった基本的な演算から始め、乗算や除算といった複雑な演算を後に行うと、丸め誤差を最小限に抑えることができます。
  3. 比較演算における注意: 浮動小数点数の比較演算は、厳密な等値判定が難しい場合があります。丸め誤差や演算誤差の影響を考慮して、適切な精度で比較演算を行う必要があります。通常は、等値判定ではなく、ある値が別の値よりも大きいか、または小さいかを判定することが推奨されます。
  4. 結果の解釈: 浮動小数点数の演算結果を解釈する際には、その精度や誤差の範囲を理解する必要があります。特に、科学計算や金融取引などの精密な計算においては、計算結果の信頼性を確保するために十分な検証と解釈が必要です。

これらの注意点を考慮することで、Javaの浮動小数点数による計算における誤差を最小限に抑えることができます。

さらに、浮動小数点数の計算における誤差を最小限に抑えるために、次のようなアプローチも考慮されます。

  1. 丸めモードの設定: Javaでは、浮動小数点数の計算における丸めモードを設定することができます。デフォルトでは、丸めモードは「デフォルト」であり、周囲に最も近い数に丸められます。しかし、必要に応じて丸めモードを変更して、計算結果に影響を与えることができます。例えば、丸め誤差を最小限に抑えるために、上向き丸め(ceiling)、下向き丸め(floor)、ゼロから遠い方向の丸め(向上丸め)、ゼロに近い方向の丸め(向下丸め)などの丸めモードを使用することができます。
  2. 有効桁数の管理: 浮動小数点数の計算においては、有効桁数の制限により誤差が生じることがあります。特に、非常に大きな数や非常に小さな数を表現する場合、有効桁数の不足により計算結果に誤差が生じることがあります。そのため、計算に使用する浮動小数点数の有効桁数を適切に管理することが重要です。必要に応じて、BigDecimalなどの精度の高いデータ型を使用して計算を行うことも考慮されます。
  3. ライブラリの活用: 数値計算に関連するライブラリを活用することで、浮動小数点数の計算における誤差を最小限に抑えることができます。これらのライブラリには、高精度な計算を行うための機能や、誤差を最小限に抑えるためのアルゴリズムが含まれています。特に、金融取引や科学計算などの精密な計算を行う場合には、これらのライブラリを活用することが推奨されます。

以上のようなアプローチを組み合わせることで、Javaの浮動小数点数を使用した計算における誤差を最小限に抑えることができます。ただし、特定の問題や要件に応じて、最適なアプローチを選択する必要があります。

0.1を10回足しても1.0にならない!

[編集]

浮動小数点数の内部表現により、一部の10進数を正確に表現することができません。例えば、0.1を浮動小数点数として表現すると、その厳密な値ではなく近似値になります。そのため、0.1を10回足しても厳密に1.0にはならない場合があります。

Javaでは、float型やdouble型を使用して浮動小数点数を表現しますが、これらの型は有限のビット数で浮動小数点数を表現するため、一部の10進数を正確に表現することができません。その結果、浮動小数点数の計算においては、丸め誤差や演算誤差が生じる可能性があります。

例えば、次のコードを見てみましょう。

double sum = 0.0;
for (int i = 0; i < 10; i++) {
    sum += 0.1;
}
System.out.println(sum); // 出力: 0.9999999999999999

このコードでは、0.1を10回足した結果が正確に1.0にならず、0.9999999999999999 という近似値になります。

このように誤差が生じるのは、内部的に浮動小数点数が2進数で扱われているためです(0.1は、2進数では循環小数になるため正確に表現できません)。

カハンの総和アルゴリズム
[編集]

誤差を補正する方法はいくつかありますが、カハンの総和アルゴリズム( Kahan summation algorithm )が代表的です。

カハンの総和アルゴリズム
public class Main {
    public static void main(String[] args) {
        double d = 0.0;
        for (int i = 0; i < 10; i++) d += 0.1;
        System.out.println(d);

        d = 0.0;
        double c = 0.0;
        for (int i = 0; i < 10; i++) {
            double y = 0.1 - c;
            double t = d + y;
            c = ( t - d ) - y;
            d = t;
        }
        System.out.println(d);

        float f = 0.0f;
        for (int i = 0; i < 10; i++) f += 0.1f;
        System.out.println(f);
        
        f = 0.0f;
        float fc = 0.0f;
        for (int i = 0; i < 10; i++) {
            float y = 0.1f - fc;
            float t = f + y;
            fc = ( t - f ) - y;
            f = t;
        }
        System.out.println(f);
    }
}
$ javac Main.java
$ java Main
0.9999999999999999
1.0
1.0000001 
1.0
Java Stream API
[編集]

また、Java Stream API も補正アルゴリズムを実装しています。

Stream APIを使った総和
import java.util.stream.DoubleStream;

class Main {
    public static void main(String[] args) {
        // DoubleStream.builder() を使用して、DoubleStream.Builderオブジェクトを作成します。
        // これは、DoubleStreamを構築するためのビルダーオブジェクトです。
        final var builder = DoubleStream.builder();
        
        // ループを10回実行し、builder.add(0.1) を使用して、ビルダーオブジェクトに0.1を追加します。
        // これにより、10回のループを通じて0.1が10回追加されます。
        for (int i = 0; i < 10; i++)
            builder.add(0.1);
        
        // builder.build() を使用して、ビルダーオブジェクトからDoubleStreamオブジェクトを構築します。
        // これにより、10回のループで追加された0.1の値が含まれたDoubleStreamが得られます。
        System.out.println(builder.build().sum());
        
        // sum() メソッドを使用して、DoubleStreamオブジェクトの合計を計算します。
        // これにより、10回のループで追加された0.1の値の合計が計算されます。
        
        // 最後に、計算された合計値が出力されます。
    }
}
1.0
DoubleStreamのメソッドsum()は、保証を行うアルゴリズムを採用しています。

優先順位と結合性

[編集]

Javaの算術演算子には、優先順位と結合性があります。以下に、一般的な算術演算子の優先順位と結合性を示します。

乗算 (*) および除算 (/、%): 乗算と除算は、加算と減算よりも高い優先順位を持ちます。また、乗算と除算は左から右に結合します。
加算 (+) および減算 (-): 加算と減算は、乗算と除算と同じ優先順位を持ちます。また、加算と減算も左から右に結合します。

優先順位

[編集]

この優先順位と結合性に基づいて、式が評価されます。例えば、次の式を考えてみましょう。

int result = 5 + 3 * 2;

この式では、乗算 (*) が加算 (+) よりも高い優先順位を持つため、まず 3 * 2 が計算されます。結果は 6 です。その後、5 と 6 の加算が行われ、最終的な結果は 11 になります。

結合性

[編集]

結合性(associativity)は、演算子が式内で連続して出現する場合に、その演算子がどのような順序で評価されるかを示す性質です。結合性は通常、左から右への結合(左結合性)または右から左への結合(右結合性)のいずれかとして定義されます。

算術演算子の結合性により、この式は左から右に評価されます。例えば、次の式を考えてみましょう。

int result = 10 - 5 - 3;

この式では、減算 (-) は左から右に結合するため、まず左側の 10 - 5 が計算されます。結果は 5 です。その後、5 から 3 を減算することで、最終的な結果は 2 になります。

Javaの算術演算子の優先順位と結合性を理解することで、式を正しく評価することができます。

比較演算子

[編集]

Javaの比較演算子は、異なる値や式の間で比較を行い、結果を真偽値(trueまたはfalse)で返します。以下は、Javaで使用される主な比較演算子です。

  1. ==:2つの値が等しいかどうかを比較します。プリミティブ型の場合、値の比較を行います。参照型の場合、オブジェクトの参照が同じかどうかを比較します。
  2. !=:2つの値が等しくないかどうかを比較します。
  3. >:左辺の値が右辺の値より大きいかどうかを比較します。
  4. <:左辺の値が右辺の値より小さいかどうかを比較します。
  5. >=:左辺の値が右辺の値以上かどうかを比較します。
  6. <=:左辺の値が右辺の値以下かどうかを比較します。

これらの比較演算子は、条件文やループ、その他の制御構造でよく使用されます。

論理演算子

[編集]

論理演算子は、論理値(真偽値)を操作するために使用されます。Javaでは、3つの主要な論理演算子があります。

  1. &&(AND):論理積演算子は、両側の式がともにtrueの場合にtrueを返します。片方でもfalseであれば、falseを返します。
  2. ||(OR):論理和演算子は、両側の式の少なくとも一方がtrueの場合にtrueを返します。両方がfalseの場合にfalseを返します。
  3. !(NOT):論理否定演算子は、式の真偽を反転させます。trueはfalseに、falseはtrueになります。

これらの演算子は、条件文やループなどの制御構造で論理式を組み立てるために使用されます。

ビット演算子

[編集]

ビット演算子は、整数のビットレベルでの演算を実行します。Javaのビット演算子は、以下のようになります。

  1. &:ビット単位のAND演算を行います。
  2. |:ビット単位のOR演算を行います。
  3. ^:ビット単位のXOR(排他的論理和)演算を行います。
  4. ~:ビット単位の補数(ビット反転)演算を行います。
  5. <<:左シフト演算子は、ビットを左に指定された数だけシフトします。
  6. >>:符号付き右シフト演算子は、ビットを右に指定された数だけシフトします。符号ビットは左端のビット(MSB)にコピーされます。
  7. >>>:符号なし右シフト演算子は、ビットを右に指定された数だけシフトします。左端のビットは0になります。

これらの演算子は、ビット単位のデータ処理や、効率的なビットマスクの作成に使用されます。

代入演算子

[編集]

代入演算子は、変数に値を割り当てるために使用されます。Javaの代入演算子には、単純な代入演算子と複合代入演算子があります。

  1. =:単純な代入演算子は、右辺の値を左辺の変数に代入します。
  2. +=:加算代入演算子は、左辺の変数に右辺の値を加算し、結果を左辺の変数に代入します。
  3. -=:減算代入演算子は、左辺の変数から右辺の値を減算し、結果を左辺の変数に代入します。
  4. *=:乗算代入演算子は、左辺の変数に右辺の値を乗算し、結果を左辺の変数に代入します。
  5. /=:除算代入演算子は、左辺の変数を右辺の値で除算し、結果を左辺の変数に代入します。
  6. %=:剰余代入演算子は、左辺の変数を右辺の値で剰余計算し、結果を左辺の変数に代入します。

これらの演算子は、変数の値を更新する際に使用され、簡潔なコードを記述するのに役立ちます。


式と演算子
public class Main {
    public static void main(String[] args) {
        int x = 5;
        int y = 3;
        
        // 算術演算子
        int sum = x + y; // 加算
        int difference = x - y; // 減算
        int product = x * y; // 乗算
        int quotient = x / y; // 除算
        int remainder = x % y; // 剰余
        
        // 比較演算子
        boolean isEqual = x == y; // xとyが等しいかどうか
        boolean isNotEqual = x != y; // xとyが等しくないかどうか
        boolean isGreaterThan = x > y; // xがyより大きいかどうか
        boolean isLessThan = x < y; // xがyより小さいかどうか
        boolean isGreaterOrEqual = x >= y; // xがy以上かどうか
        boolean isLessOrEqual = x <= y; // xがy以下かどうか
        
        // 論理演算子
        boolean andResult = (x > 0) && (y < 0); // 論理積(AND)
        boolean orResult = (x > 0) || (y < 0); // 論理和(OR)
        boolean notResult = !(x > 0); // 論理否定(NOT)
        
        // ビット演算子
        int bitAnd = x & y; // ビット単位のAND
        int bitOr = x | y; // ビット単位のOR
        int bitXor = x ^ y; // ビット単位のXOR
        int bitComplementX = ~x; // ビット単位の補数
        int leftShift = x << 1; // 左シフト
        int rightShift = x >> 1; // 右シフト
        
        // 代入演算子
        int a = 10;
        a += 5; // a = a + 5
        int b = 20;
        b -= 3; // b = b - 3
    }
}
このJavaプログラムでは、算術演算子、比較演算子、論理演算子、ビット演算子、代入演算子が使用されています。コメント中には各演算子の説明が含まれており、それぞれの演算子が何を行うかが明確に示されています。

用語集

[編集]
  1. 式と演算子 (Expression and Operators):
    • 式 (Expression): プログラミングにおいて、値、演算子、変数、関数呼び出しなどから構成される計算を表す文法構造。プログラム内で評価され、結果の値を生成する。
    • 演算子 (Operator): 式内で値や変数を操作するための記号やキーワード。算術演算子、比較演算子、論理演算子、ビット演算子、代入演算子などがある。
  2. Javaにおける式と演算子 (Expression and Operators in Java):
    • 算術演算子 (Arithmetic Operators): 加算、減算、乗算、除算、剰余など、数値データ型の間で算術演算を実行するための演算子。
    • 比較演算子 (Comparison Operators): 等しい、等しくない、大なり、小なりなど、値や式の比較を行う演算子。
    • 論理演算子 (Logical Operators): 論理積 (AND)、論理和 (OR)、否定 (NOT) など、真偽値を操作するための演算子。
    • ビット演算子 (Bitwise Operators): 論理積、論理和、排他的論理和、否定など、ビット単位の操作に使用される演算子。
    • 代入演算子 (Assignment Operators): 代入、加算代入、減算代入、乗算代入など、変数に値を代入する演算子。
  3. 算術演算子 (Arithmetic Operators in Java):
    • 加算 (Addition): +。整数や浮動小数点数の加算。
    • 減算 (Subtraction): -。整数や浮動小数点数の減算。
    • 乗算 (Multiplication): *。整数や浮動小数点数の乗算。
    • 除算 (Division): /。浮動小数点数の除算。整数と浮動小数点数の場合もあり。
    • 剰余 (Modulus): %。整数や浮動小数点数の剰余。
  4. 多様な算術演算子の例 (Various Arithmetic Operators Example in Java):
    • Javaで異なるデータ型での算術演算子の使用例。
  5. InfinityとNaN (Infinity and NaN in Java):
    • Infinity (無限大): 有限の数値を0.0で割った場合やオーバーフローが発生した場合に発生。Double.POSITIVE_INFINITYで表現される。
    • -Infinity (負の無限大): 有限の負の数値を0.0で割った場合やオーバーフローが発生した場合に発生。Double.NEGATIVE_INFINITYで表現される。
    • NaN (非数): 0を0で割った場合や不正な演算が行われた場合に発生。Double.NaNで表現され、数値としての意味を持たないことを示す。
男性尿道口流脓吃什么药最管用 水痘能吃什么 nbr是什么材料 含五行属什么 枸杞加什么泡水喝壮阳
撤退性出血是什么颜色 驾驶证照片是什么底色 十二月六号是什么星座 随诊是什么意思 皮肤病挂什么科
脚突然抽筋是什么原因 血脂高不能吃什么 寓言故事有什么特点 市局副局长什么级别 风疟病是什么意思
禅意是什么意思 afi是胎儿的什么意思 身主天机是什么意思 种植牙有什么风险和后遗症 胸径是什么意思
kiki是什么意思hcv8jop0ns7r.cn 晚上睡觉流口水是什么原因hcv9jop1ns7r.cn 计数是什么意思hcv9jop5ns1r.cn 09年属什么chuanglingweilai.com m什么单位hcv8jop3ns6r.cn
为什么会阑尾炎hcv9jop6ns5r.cn 砼为什么念hunhcv8jop8ns4r.cn 胎儿双顶径偏大是什么原因gangsutong.com 湿气重吃什么中成药zsyouku.com mlb是什么牌子hcv8jop1ns9r.cn
吃什么健脾hcv8jop1ns6r.cn 伤官运是什么意思hcv9jop3ns2r.cn 94是什么意思hcv8jop7ns5r.cn 双字五行属什么hcv7jop5ns6r.cn 金鱼吊兰什么时候开花hcv8jop9ns4r.cn
大米放什么不生虫子hcv8jop2ns2r.cn 草龟吃什么蔬菜hcv8jop5ns7r.cn 大战三百回合是什么意思hcv9jop5ns3r.cn hello什么意思wuhaiwuya.com 池塘边的榕树上是什么歌hcv8jop9ns9r.cn
百度