Passing float values to C

From: Garry (ggkraemer_at_cox.net)
Date: 02/12/05


Date: 12 Feb 2005 08:58:43 -0800

ADA experts, what am I doing wrong?
I want to be able to pass float values (single and double precision) to
C. I have not been successful in getting it to work.

TIA

Garry

Code follows:

/* marktime.c */

#include <stdio.h>
#include <string.h>

/* C printf int routine */
void cprintfi(char *mesg, int *t1) {
        char dbgbuf[512];

        sprintf(dbgbuf,mesg,t1);
        marktime(dbgbuf);
}

/* C printf short routine */
void cprintfs(char *mesg, short *t1) {
        char dbgbuf[512];

        sprintf(dbgbuf,mesg,t1);
        marktime(dbgbuf);
}

/* C printf long routine */
void cprintfl(char *mesg, long *t1) {
        char dbgbuf[512];

        sprintf(dbgbuf,mesg,t1);
        marktime(dbgbuf);
}

/* C printf string routine */
void cprintfstr(char *mesg) {
        char dbgbuf[512];

        memset(dbgbuf,0,sizeof(dbgbuf));
        sprintf(dbgbuf,mesg);
        marktime(dbgbuf);
}

/* C printf float routine */
void cprintff(char *mesg, float *t1) {
        char dbgbuf[512];

        printf("cprintff: t1=%f = %g\n",t1,t1);
        sprintf(dbgbuf,mesg,t1);
        marktime(dbgbuf);

}

/* C printf double float routine */
void cprintfdf(char *mesg, float *t1) {
        char dbgbuf[512];

        printf("cprintfdf: t1=%f = %g\n",t1,t1);
        sprintf(dbgbuf,mesg,t1);
        marktime(dbgbuf);
}

/* marktime.c */

-- hsdbg.ads --

with Interfaces.C;
with Interfaces.C.Strings;

package HSDBG is

-- C printf str routine
      procedure cprintfstr(Variable : Interfaces.C.Strings.chars_ptr);
      pragma Import(C, cprintfstr, "cprintfstr");

-- C printf int routine
      procedure cprintfi(Variable : Interfaces.C.Strings.chars_ptr; val
: Integer );
      pragma Import(C, cprintfi, "cprintfi");

-- C printf short routine
      procedure cprintfs(Variable : Interfaces.C.Strings.chars_ptr; val
: Interfaces.C.short );
      pragma Import(C, cprintfs, "cprintfs");

-- C printf long routine
      procedure cprintfl(Variable : Interfaces.C.Strings.chars_ptr; val
: Interfaces.C.long );
      pragma Import(C, cprintfl, "cprintfl");

-- C printf float routine (32 bits)
      procedure cprintff(Variable : Interfaces.C.Strings.chars_ptr; val
: Interfaces.C.C_float );
      pragma Import(C, cprintff, "cprintff");

-- C printf double float routine (64 bits)
      procedure cprintfdf(Variable : Interfaces.C.Strings.chars_ptr;
val : Interfaces.C.C_float );
      pragma Import(C, cprintfdf, "cprintfdf");

end HSDBG;

-- hsdbg.ads --

-- tst.adb --
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;
with hsdbg; use hsdbg;

procedure tst is

   PI : constant := 3.14159_26535_8979;
   type REAL is digits 6; -- Single Precision
Floating Point
   type LONG_REAL is digits 9; -- Double Precision
Floating Point
   type INTEGER_SHORT is range -32768..32767; -- 16 Bit Integer
   type INTEGER_LONG is range -2**31.. 2**31-1; -- 32 Bit Integer
   type RADIANS_LONG is new LONG_REAL range -3.0*PI..3.0*PI;
   subtype LATITUDE_TYPE is RADIANS_LONG range -PI/2.0 .. PI/2.0;
   subtype LONGITUDE_TYPE is RADIANS_LONG range -PI..PI;

   C_Format1 : chars_ptr := New_String("ADA routine: value=%d");
   C_Format2 : chars_ptr := New_String("Testing of C strings");
   C_Format3 : chars_ptr := New_String("ADA calling cprintff:
value=%f");
   C_Format4 : chars_ptr := New_String("ADA calling cprintfdf:
value=%f");
   step : Integer;
   package Int_IO is new Integer_IO (Integer);
   use Int_IO;
   package Flt_IO is new Float_IO (float);
   use Flt_IO;

   cnt : Integer;
   s : short;
   l : long;
   lat : LATITUDE_TYPE;
   lon : LONGITUDE_TYPE;
   f : float;
   d : double;

begin
   put_line ("test started");
   step := 1;
   l :=1234567890;
   s:=255;
-- lat := 1.5678;
-- lon := -1.5678;
   f := 123.456789;
   d := 123456789.9876543210;
-- cprintfi(C_Format1,step);
-- cnt:=22;
-- cprintfi(C_Format1,cnt);
-- cprintfstr(C_Format2);
-- cprintfs(C_Format1,s);
-- put_line("calling cprintfl(C_Format1,l)");
-- cprintfl(C_Format1,l);

put_line("floating value of f = ");
Ada.Float_Text_IO.put(f);new_line;
put_line("calling cprintff(C_Format3,f)");
   cprintff(C_Format3,C_Float(f));
put_line("calling cprintfdf(C_Format4,d)");
   cprintfdf(C_Format4,C_Float(d));
put_line("end of my test program");

end tst;
-- tst.adb --

go1.bat
gcc -c marktime.c
gnatmake -c tst.adb
gnatbind tst.ali
gnatlink tst.ali marktime.o



Relevant Pages

  • Re: Floating Point Approximations.
    ... (chosen as 5 decimal places based on the useful precision of the float ... int main{ ... printf; ... point for using, in certain circumstances, BCD math instead of binary ...
    (comp.databases.theory)
  • Re: Floating Point Approximations.
    ... The aware method is aware of both the limitation in the representations and in the range of interest (chosen as 5 decimal places based on the useful precision of the float type.) ... This is such a trivial example that it should make all programmers who don't know what they are doing shudder. ... int main{ ... printf; ...
    (comp.databases.theory)
  • Re: Mystery Values
    ... the actual number of digits following the decimal. ... And then instead of the nice Float compare routine shared earlier, ... When this is the case, for display purposes, I must covert .03125 to ...
    (comp.lang.basic.visual.misc)
  • Re: Some sort of weird round off error -- please help!
    ... I have a logical contradiction as ... float Sum=0.0; ... the declaration of N and the last printf, ... but that doesn't restore the lost precision). ...
    (comp.lang.c)
  • Re: Floating Point Approximations.
    ... The naive method below ignores rounding. ... The aware method is aware of both the limitation in the representations and in the range of interest (chosen as 5 decimal places based on the useful precision of the float type.) ... int main{ ... printf; ...
    (comp.databases.theory)