mathf.h は何のために有るのか

RX621のマニュアルに math.h と mathf.h が有ります。
mathf.h は、次の説明が書かれています。

<mathf.h>ではANSI 規格規定外の単精度形式の数学関数の宣言とマクロの定義をしています。
各関数はfloat 型の実引数を受け取り、float 型の値を返します。

math.h の float 型を使えば良いと思うのですが、何故 mathf.h が有るのでしょう。
「ANSI 規格規定外の単精度形式」と言うのが引っ掛かります。何か長所が有って、ルネサス独自の規格なのでしょうか。

Parents
  • リカルドさん、こんにちは。NoMaYです。

    まず、acosf()などのfloat型系の数学関数とacosl()などのlong double型系の数学関数はC99で追加された仕様であり、C90には無かった仕様でした。H8コンパイラの最終版V7.0.0のドキュメントでは既にC99対応のオプションがありましたので、まさにmathf.hが導入された時期とH8コンパイラがC99に対応した時期とのタイミング関係は私では分かりませんけれども、mathf.hの方が先だった可能性もありそうに思いました。

    acos, acosf, acosl - cppreference.com
    ja.cppreference.com/w/c/numeric/math/acos

    ちなみに、H8コンパイラの最終版V7.0.0のインクルードフォルダを見てみたところ、C89とC99の2つのフォルダに分かれていました。そして、C89というフォルダのmath.hとmathf.hは以下の通りになっていました。そのmath.hにはacosf()などのfloat型系の数学関数はありませんでした。(他方で、C99というフォルダにはmathf.hはありませんでした。)

    HEW/Tools/Renesas/H8/7_0_0/include/C89/math.h

    /*------------------------------------------------------------------------------*/
    /* H8S,H8/300 SERIES C/C++ Compiler Ver. 7.0                                    */
    /* Copyright (C) 1994,2007 Renesas Technology Corp. and Renesas Solutions Corp. */
    /* Copyright (C) 2000 Hitachi, Ltd.                                             */
    /* Copyright (C) 1994,2007 Hitachi Information & Control Solutions, Ltd.        */
    /* All rights reserved.                                                         */
    /*------------------------------------------------------------------------------*/

    #ifndef _MATH_H
    #define _MATH_H

    #define ERANGE  1100
    #define EDOM    1101

    #ifndef HUGE_VAL
    #ifdef __FLT__
    extern const float _HUGE_VALF;
    #define HUGE_VAL _HUGE_VALF
    #else
    extern const double _HUGE_VAL;
    #define HUGE_VAL _HUGE_VAL
    #endif
    #endif

    #ifdef __cplusplus
    extern "C" {
    #endif

    #ifndef errno
    #ifdef _REENTRANT
    extern int *errno_addr(void);
    #define errno (*errno_addr())
    #else
    extern volatile int _errno;
    #define errno _errno
    #endif
    #endif

    extern double acos(double);
    extern double asin(double);
    extern double atan(double);
    extern double atan2(double, double);
    extern double cos(double);
    extern double sin(double);
    extern double tan(double);
    extern double cosh(double);
    extern double sinh(double);
    extern double tanh(double);
    extern double exp(double);
    extern double frexp(double, int *);
    extern double ldexp(double, int);
    extern double log(double);
    extern double log10(double);
    extern double modf(double, double *);
    extern double pow(double, double);
    extern double sqrt(double);
    extern double ceil(double);
    extern double fabs(double);
    extern double floor(double);
    extern double fmod(double, double);
    #ifdef __cplusplus
    }
    #endif

    #endif /* _MATH_H */

     
    HEW/Tools/Renesas/H8/7_0_0/include/C89/mathf.h

    /*------------------------------------------------------------------------------*/
    /* H8S,H8/300 SERIES C/C++ Compiler Ver. 7.0                                    */
    /* Copyright (C) 1994,2007 Renesas Technology Corp. and Renesas Solutions Corp. */
    /* Copyright (C) 2000 Hitachi, Ltd.                                             */
    /* Copyright (C) 1994,2007 Hitachi Information & Control Solutions, Ltd.        */
    /* All rights reserved.                                                         */
    /*------------------------------------------------------------------------------*/

    #ifndef _MATHF_H
    #define _MATHF_H

    #define ERANGE  1100
    #define EDOM    1101

    extern const float _HUGE_VALF;
    #define HUGE_VALF _HUGE_VALF

    #ifndef HUGE_VAL
    #ifdef __FLT__
    #define HUGE_VAL _HUGE_VALF
    #else
    extern const double _HUGE_VAL;
    #define HUGE_VAL _HUGE_VAL
    #endif
    #endif

    #ifdef __cplusplus
    extern "C" {
    #endif

    #ifndef errno
    #ifdef _REENTRANT
    extern int *errno_addr(void);
    #define errno (*errno_addr())
    #else
    extern volatile int _errno;
    #define errno _errno
    #endif
    #endif

    extern float acosf(float);
    extern float asinf(float);
    extern float atanf(float);
    extern float atan2f(float, float);
    extern float cosf(float);
    extern float sinf(float);
    extern float tanf(float);
    extern float coshf(float);
    extern float sinhf(float);
    extern float tanhf(float);
    extern float expf(float);
    extern float frexpf(float, int *);
    extern float ldexpf(float, int);
    extern float logf(float);
    extern float log10f(float);
    extern float modff(float, float *);
    extern float powf(float, float);
    extern float sqrtf(float);
    extern float ceilf(float);
    extern float fabsf(float);
    extern float floorf(float);
    extern float fmodf(float, float);
    #ifdef __cplusplus
    }
    #endif

    #endif /* _MATHF_H */

     

  • リカルド です。

    ノマイさん、回答有難う御座います。

    >acosf()などのfloat型系の数学関数とacosl()などのlong double型系の数学関数はC99で追加された仕様であり、C90には無かった仕様でした。


    倍精度が先で、単精度が後から後からと言うのがおかしいですね。次のように想像してみました。

    ・コンピュータのハードが貧弱な黎明期に単精度が出来た。
    ・C言語が出来る頃にはハードが発展し、C言語では倍精度を標準とした。
    ・速度優先の為にC99で単精度を入れた。

  • リカルドさん、こんにちは。NoMaYです。

    確かに、単精度浮動小数点数が先なのですけれども、たぶんリカルドさんが思っているよりも、遥かに大昔ではないかと。

    IBM 704 - ウィキペディア
    ja.wikipedia.org/wiki/IBM_704

    IBM 704は、IBMが1954年4月に発表した、浮動小数点数演算ハードウェアを搭載した初の量産型コンピュータである。


    701と同様に、704は真空管論理回路と36ビットのバイナリワードを使用した。


    IBM 7090 - ウィキペディア
    ja.wikipedia.org/wiki/IBM_7090

    709は704を強化したマシンだったが、709がリリースされたころには真空管からトランジスタへと時代が移りつつあった。そこでIBMは709開発チームにトランジスタ版の後継機開発を指示した。このプロジェクトは709-T(Tは Transistorized の意)と呼ばれたが、それを「セブン・オー・ナインティ」と発音したことから、機種名が7090となった。


    IBM 7094 (1962年9月)

    倍精度浮動小数点数と関連する命令が追加されているが、7090とは大部分で互換性が保たれている。


    [追記]

    PDP-11 - ウィキペディア
    ja.wikipedia.org/wiki/PDP-11

    PDP-11ファミリは1970年1月に発表され、同年前半に出荷が開始された。


    それでも、C言語はPDP-11で実装する際にPDP-11の持つ細かい利点を活用しており、そのために後のプロセッサの設計に影響を与えた可能性はある。


  • こんにちは、

    C言語云々というと、K&Rまで遡らないと。で最初のC言語仕様でライブラリ関数は付録扱い。

    関数の引数は、int か double が標準でした。

    また、20世紀の頃、組込みはほぼ、アセンブラだったという事も意味があるかもしれません。

Reply
  • こんにちは、

    C言語云々というと、K&Rまで遡らないと。で最初のC言語仕様でライブラリ関数は付録扱い。

    関数の引数は、int か double が標準でした。

    また、20世紀の頃、組込みはほぼ、アセンブラだったという事も意味があるかもしれません。

Children
No Data