iostream et STL
Re: iostream et STL
It shouldn't be that hard to add a minimal support for 6 digits display of doubles. I'll probably try to do that myself until a better solution is implemented, like I'm doing for the STL.
Does strtod work?
Is there a reason to force -fno-exceptions in nspire-g++ other than the code size? Removing all try/catch and throw in ustl willl result in a much less stable port of C++ projects who expect errors to throw an exception, so that they don't care of errors by hand themselves.
Does strtod work?
Is there a reason to force -fno-exceptions in nspire-g++ other than the code size? Removing all try/catch and throw in ustl willl result in a much less stable port of C++ projects who expect errors to throw an exception, so that they don't care of errors by hand themselves.
-
parisseVIP++
Niveau 12: CP (Calculatrice sur Pattes)- Posts: 3721
- Joined: 13 Dec 2013, 16:35
- Gender:
- Calculator(s):→ MyCalcs profile
Re: iostream et STL
strtod does not work. Here is a working one, should probably replace the system call in os.h and be somewhere in a library.
- Code: Select all
/*
* strtod.c --
*
* Source code for the "strtod" library procedure.
*
* Copyright (c) 1988-1993 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: strtod.c,v 1.1.1.4 2003/03/06 00:09:04 landonf Exp $
*/
#include <ctype.h>
#include <errno.h>
typedef unsigned char UCHAR;
static int maxExponent = 511; /* Largest possible base 10 exponent. Any
* exponent larger than this will already
* produce underflow or overflow, so there's
* no need to worry about additional digits.
*/
static double powersOf10[] = { /* Table giving binary powers of 10. Entry */
10., /* is 10^2^i. Used to convert decimal */
100., /* exponents into floating-point numbers. */
1.0e4,
1.0e8,
1.0e16,
1.0e32,
1.0e64,
1.0e128,
1.0e256
};
/*
*----------------------------------------------------------------------
*
* strtod --
*
* This procedure converts a floating-point number from an ASCII
* decimal representation to internal double-precision format.
*
* Results:
* The return value is the double-precision floating-point
* representation of the characters in string. If endPtr isn't
* NULL, then *endPtr is filled in with the address of the
* next character after the last one that was part of the
* floating-point number.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
double
strtod(const char * string, char ** endPtr)
/* A decimal ASCII floating-point number,
* optionally preceded by white space.
* Must have form "-I.FE-X", where I is the
* integer part of the mantissa, F is the
* fractional part of the mantissa, and X
* is the exponent. Either of the signs
* may be "+", "-", or omitted. Either I
* or F may be omitted, or both. The decimal
* point isn't necessary unless F is present.
* The "E" may actually be an "e". E and X
* may both be omitted (but not just one).
*/
/* If non-NULL, store terminating character's
* address here. */
{
int sign, expSign = 0;
double fraction, dblExp, *d;
register const char *p;
register int c;
int exp = 0; /* Exponent read from "EX" field. */
int fracExp = 0; /* Exponent that derives from the fractional
* part. Under normal circumstatnces, it is
* the negative of the number of digits in F.
* However, if I is very long, the last digits
* of I get dropped (otherwise a long I with a
* large negative exponent could cause an
* unnecessary overflow on I alone). In this
* case, fracExp is incremented one for each
* dropped digit. */
int mantSize; /* Number of digits in mantissa. */
int decPt; /* Number of mantissa digits BEFORE decimal
* point. */
const char *pExp; /* Temporarily holds location of exponent
* in string. */
/*
* Strip off leading blanks and check for a sign.
*/
p = string;
while (isspace(UCHAR(*p))) {
p += 1;
}
if (*p == '-') {
sign = 1;
p += 1;
} else {
if (*p == '+') {
p += 1;
}
sign = 0;
}
/*
* Count the number of digits in the mantissa (including the decimal
* point), and also locate the decimal point.
*/
decPt = -1;
for (mantSize = 0; ; mantSize += 1)
{
c = *p;
if (!isdigit(c)) {
if ((c != '.') || (decPt >= 0)) {
break;
}
decPt = mantSize;
}
p += 1;
}
/*
* Now suck up the digits in the mantissa. Use two integers to
* collect 9 digits each (this is faster than using floating-point).
* If the mantissa has more than 18 digits, ignore the extras, since
* they can't affect the value anyway.
*/
pExp = p;
p -= mantSize;
if (decPt < 0) {
decPt = mantSize;
} else {
mantSize -= 1; /* One of the digits was the point. */
}
if (mantSize > 18) {
fracExp = decPt - 18;
mantSize = 18;
} else {
fracExp = decPt - mantSize;
}
if (mantSize == 0) {
fraction = 0.0;
p = string;
goto done;
} else {
int frac1, frac2;
frac1 = 0;
for ( ; mantSize > 9; mantSize -= 1)
{
c = *p;
p += 1;
if (c == '.') {
c = *p;
p += 1;
}
frac1 = 10*frac1 + (c - '0');
}
frac2 = 0;
for (; mantSize > 0; mantSize -= 1)
{
c = *p;
p += 1;
if (c == '.') {
c = *p;
p += 1;
}
frac2 = 10*frac2 + (c - '0');
}
fraction = (1.0e9 * frac1) + frac2;
}
/*
* Skim off the exponent.
*/
p = pExp;
if ((*p == 'E') || (*p == 'e')) {
p += 1;
if (*p == '-') {
expSign = 1;
p += 1;
} else {
if (*p == '+') {
p += 1;
}
expSign = 0;
}
if (!isdigit(UCHAR(*p))) {
p = pExp;
goto done;
}
while (isdigit(UCHAR(*p))) {
exp = exp * 10 + (*p - '0');
p += 1;
}
}
if (expSign) {
exp = fracExp - exp;
} else {
exp = fracExp + exp;
}
/*
* Generate a floating-point number that represents the exponent.
* Do this by processing the exponent one bit at a time to combine
* many powers of 2 of 10. Then combine the exponent with the
* fraction.
*/
if (exp < 0) {
expSign = 1;
exp = -exp;
} else {
expSign = 0;
}
if (exp > maxExponent) {
exp = maxExponent;
errno = ERANGE;
}
dblExp = 1.0;
for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
if (exp & 01) {
dblExp *= *d;
}
}
if (expSign) {
fraction /= dblExp;
} else {
fraction *= dblExp;
}
done:
if (endPtr != 0) {
*endPtr = (char *) p;
}
if (sign) {
return -fraction;
}
return fraction;
}
-
parisseVIP++
Niveau 12: CP (Calculatrice sur Pattes)- Posts: 3721
- Joined: 13 Dec 2013, 16:35
- Gender:
- Calculator(s):→ MyCalcs profile
Re: iostream et STL
parisse wrote:strtod does not work. Here is a working one, should probably replace the system call in os.h and be somewhere in a library.
Il y a effectivement une note dans les tests de ndless qui dit que strtod ne marche pas.
C'est quand même étrange, ça m'étonnerait que TI ait une version non fonctionnelle de strtod dans leur OS. Et puis vu la tête de ce qui s'appelle actuellement strtod, ça a bien l'air d'être strtod.
-
ExcaleAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)- Posts: 2955
- Images: 3
- Joined: 10 Sep 2010, 00:00
- Gender:
- Calculator(s):→ MyCalcs profile
Re: iostream et STL
On the TI-68k platform, AMS versions older than 2.04 (2.05 ?) contained a bug in strtod (no special handling of NULL as endptr argument), as I had noticed when disassembling some strtod-using code produced by TIFS - but I'd be surprised to see the same bug in the Nspire series, a decade later.
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
-
Lionel DebrouxSuper Modo
Niveau 14: CI (Calculateur de l'Infini)- Posts: 6869
- Joined: 23 Dec 2009, 00:00
- Location: France
- Gender:
- Calculator(s):→ MyCalcs profile
- Class: -
- GitHub: debrouxl
Re: iostream et STL
Lionel Debroux wrote:On the TI-68k platform, AMS versions older than 2.04 (2.05 ?) contained a bug in strtod (no special handling of NULL as endptr argument), as I had noticed when disassembling some strtod-using code produced by TIFS - but I'd be surprised to see the same bug in the Nspire series, a decade later.
- Code: Select all
MOV R6, R1
...
CMP R6, #0
STRNE R4, [R6]
Seems to be handling it on TI-Nspire.
-
ExcaleAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)- Posts: 2955
- Images: 3
- Joined: 10 Sep 2010, 00:00
- Gender:
- Calculator(s):→ MyCalcs profile
Re: iostream et STL
parisse wrote:Is there a reason to force -fno-exceptions in nspire-g++ other than the code size? Removing all try/catch and throw in ustl willl result in a much less stable port of C++ projects who expect errors to throw an exception, so that they don't care of errors by hand themselves.
Exceptions are currently not supported by Ndless. Tangrs said that we need a runtime exception library and a stack unwinding library.
More information can be found here.
-
compu
Niveau 0: MI (Membre Inactif)- Posts: 2
- Joined: 01 Jan 2013, 17:15
- Gender:
- Calculator(s):→ MyCalcs profile
Re: iostream et STL
parisse wrote:strtod does not work. Here is a working one, should probably replace the system call in os.h and be somewhere in a library.
Yagarto doubles representation is reversed compared to TI's one. Maybe it's the same problem for floats, I've never investigated.
From bsl :
- Code: Select all
double dswap(double v)
{
union {
unsigned long long i;
double d;
} conv;
conv.d = v;
conv.i = (conv.i << 32) | (conv.i >> 32);
return conv.d;
}
-
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)- Posts: 6414
- Images: 22
- Joined: 27 Nov 2008, 00:00
- Location: 0x1AACC355
- Gender:
- Calculator(s):→ MyCalcs profile
- Class: BAC+5: Epita (ING3)
Re: iostream et STL
Does the TI OS use double or do they use BCD for their own arithmetic? If it's the second, this could explain the poor support for double.
-
parisseVIP++
Niveau 12: CP (Calculatrice sur Pattes)- Posts: 3721
- Joined: 13 Dec 2013, 16:35
- Gender:
- Calculator(s):→ MyCalcs profile
Re: iostream et STL
At least the Lua part uses binary double floats.
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
-
Lionel DebrouxSuper Modo
Niveau 14: CI (Calculateur de l'Infini)- Posts: 6869
- Joined: 23 Dec 2009, 00:00
- Location: France
- Gender:
- Calculator(s):→ MyCalcs profile
- Class: -
- GitHub: debrouxl
Re: iostream et STL
I confirm that the TI OS uses base 10 floats. You can prove that by the following operation results:
(2^46+1.)-2^46-1 returns 0
(2^47+1.)-2^47-1 returns -1
and 10. is the first value of b>=2 such that (2^47+b)-2^47-b is 0 (where b is written as a float with a dot at the end).
Can you make the same checks for lua?
Here is a small double to string converter, far from complete when compared to sprintf, but that should be good enough for a basic implementation
(2^46+1.)-2^46-1 returns 0
(2^47+1.)-2^47-1 returns -1
and 10. is the first value of b>=2 such that (2^47+b)-2^47-b is 0 (where b is written as a float with a dot at the end).
Can you make the same checks for lua?
Here is a small double to string converter, far from complete when compared to sprintf, but that should be good enough for a basic implementation
- Code: Select all
#include <math.h>
#include <stdio.h>
const double mlog10=2.3025850929940457;
char * dtostr(double d,int digits,char * s){
if (d<0){
s[0]='-';
s[1]=0;
dtostr(-d,digits,s+1);
return s;
}
if (d==0){
s[0]='0';
s[1]=0;
return s;
}
int e=ceil(log(d)/mlog10);
if (digits>16)
digits=16;
if (e>=0 && e<digits && digits-e<=9){
int m1=d;
d=d-m1;
int m2=d*exp((digits-e)*mlog10)+.5;
sprintf(s,"%i.%i",m1,m2);
return s;
}
d *= exp((digits-e)*mlog10);
s[0]='0';
s[1]='.';
if (digits>9){
int m1=d/1e9;
int m2=d-m1*1e9+.5;
if (e)
sprintf(s+2,"%i%ie%i",m1,m2,e);
else
sprintf(s+2,"%i%i",m1,m2);
}
else {
int m=d+.5;
if (e)
sprintf(s+2,"%ie%i",m,e);
else
sprintf(s+2,"%i",m);
}
return s;
}
-
parisseVIP++
Niveau 12: CP (Calculatrice sur Pattes)- Posts: 3721
- Joined: 13 Dec 2013, 16:35
- Gender:
- Calculator(s):→ MyCalcs profile
Return to Native: Ndless, Linux, ...
Who is online
Users browsing this forum: ClaudeBot [spider] and 3 guests