atolfp.c revision 293893
1216417Sdelphij/* 21590Srgrimes * atolfp - convert an ascii string to an l_fp number 31590Srgrimes */ 41590Srgrimes#include <config.h> 51590Srgrimes#include <stdio.h> 61590Srgrimes#include <ctype.h> 71590Srgrimes 81590Srgrimes#include "ntp_fp.h" 91590Srgrimes#include "ntp_string.h" 101590Srgrimes#include "ntp_assert.h" 111590Srgrimes 121590Srgrimes/* 131590Srgrimes * Powers of 10 141590Srgrimes */ 151590Srgrimesstatic u_long ten_to_the_n[10] = { 161590Srgrimes 0, 171590Srgrimes 10, 181590Srgrimes 100, 191590Srgrimes 1000, 201590Srgrimes 10000, 211590Srgrimes 100000, 221590Srgrimes 1000000, 231590Srgrimes 10000000, 241590Srgrimes 100000000, 251590Srgrimes 1000000000, 261590Srgrimes}; 271590Srgrimes 281590Srgrimes 291590Srgrimesint 30216310Sjillesatolfp( 311590Srgrimes const char *str, 3220409Ssteve l_fp *lfp 331590Srgrimes ) 341590Srgrimes{ 351590Srgrimes register const char *cp; 361590Srgrimes register u_long dec_i; 371590Srgrimes register u_long dec_f; 381590Srgrimes char *ind; 3965429Simp int ndec; 4020409Ssteve int isneg; 4165429Simp static const char *digits = "0123456789"; 4259435Scracauer 4359435Scracauer REQUIRE(str != NULL); 441590Srgrimes 451590Srgrimes isneg = 0; 461590Srgrimes dec_i = dec_f = 0; 471590Srgrimes ndec = 0; 481590Srgrimes cp = str; 491590Srgrimes 50148721Sstefanf /* 511590Srgrimes * We understand numbers of the form: 52216417Sdelphij * 531590Srgrimes * [spaces][-|+][digits][.][digits][spaces|\n|\0] 541590Srgrimes */ 551590Srgrimes while (isspace((unsigned char)*cp)) 5627966Ssteve cp++; 571590Srgrimes 581590Srgrimes if (*cp == '-') { 591590Srgrimes cp++; 6012730Sjoerg isneg = 1; 6170256Sben } 62215520Sjilles 6341582Sbde if (*cp == '+') 6441582Sbde cp++; 6541582Sbde 6641582Sbde if (*cp != '.' && !isdigit((unsigned char)*cp)) 671590Srgrimes return 0; 681590Srgrimes 6995409Stjr while (*cp != '\0' && (ind = strchr(digits, *cp)) != NULL) { 7018613Speter dec_i = (dec_i << 3) + (dec_i << 1); /* multiply by 10 */ 7198424Stjr dec_i += (u_long)(ind - digits); 7298424Stjr cp++; 7318613Speter } 741590Srgrimes 7518613Speter if (*cp != '\0' && !isspace((unsigned char)*cp)) { 7698424Stjr if (*cp++ != '.') 7718613Speter return 0; 781590Srgrimes 7918613Speter while (ndec < 9 && *cp != '\0' 8018613Speter && (ind = strchr(digits, *cp)) != NULL) { 8118613Speter ndec++; 8218613Speter dec_f = (dec_f << 3) + (dec_f << 1); /* *10 */ 8318613Speter dec_f += (u_long)(ind - digits); 8495409Stjr cp++; 851590Srgrimes } 8692921Simp 87215520Sjilles while (isdigit((unsigned char)*cp)) 88145078Sstefanf cp++; 8992921Simp 90143906Sdas if (*cp != '\0' && !isspace((unsigned char)*cp)) 9192921Simp return 0; 92148721Sstefanf } 9395409Stjr 9495409Stjr if (ndec > 0) { 95216418Sdelphij register u_long tmp; 9692921Simp register u_long bit; 971590Srgrimes register u_long ten_fact; 981590Srgrimes 991590Srgrimes ten_fact = ten_to_the_n[ndec]; 1001590Srgrimes 101102944Sdwmalone tmp = 0; 1021590Srgrimes bit = 0x80000000; 103145078Sstefanf while (bit != 0) { 104216447Sdelphij dec_f <<= 1; 105145061Sstefanf if (dec_f >= ten_fact) { 1061590Srgrimes tmp |= bit; 107216310Sjilles dec_f -= ten_fact; 108216424Sdelphij } 10972304Sache bit >>= 1; 110215520Sjilles } 111215520Sjilles if ((dec_f << 1) > ten_fact) 112215520Sjilles tmp++; 113216447Sdelphij dec_f = tmp; 114216447Sdelphij } 115216447Sdelphij 116216447Sdelphij if (isneg) 117216447Sdelphij M_NEG(dec_i, dec_f); 118216447Sdelphij 119216447Sdelphij lfp->l_ui = dec_i; 120216447Sdelphij lfp->l_uf = dec_f; 121216447Sdelphij return 1; 1221590Srgrimes} 1231590Srgrimes