strtold: set errno to ERANGE on underflow per POSIX
https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtod.html
This commit is contained in:
		
				
					committed by
					
						 Corinna Vinschen
						Corinna Vinschen
					
				
			
			
				
	
			
			
			
						parent
						
							29ba52da95
						
					
				
				
					commit
					c81a76b3b9
				
			| @@ -348,6 +348,9 @@ rvOK (struct _reent *p, double d, FPI *fpi, Long *exp, __ULong *bits, int exact, | |||||||
| 		if (k > nb || fpi->sudden_underflow) { | 		if (k > nb || fpi->sudden_underflow) { | ||||||
| 			b->_wds = inex = 0; | 			b->_wds = inex = 0; | ||||||
| 			*irv = STRTOG_Underflow | STRTOG_Inexlo; | 			*irv = STRTOG_Underflow | STRTOG_Inexlo; | ||||||
|  | #ifndef NO_ERRNO | ||||||
|  | 			errno = ERANGE; | ||||||
|  | #endif | ||||||
| 			} | 			} | ||||||
| 		else { | 		else { | ||||||
| 			k1 = k - 1; | 			k1 = k - 1; | ||||||
| @@ -362,9 +365,15 @@ rvOK (struct _reent *p, double d, FPI *fpi, Long *exp, __ULong *bits, int exact, | |||||||
| 			if (carry) { | 			if (carry) { | ||||||
| 				b = increment(p, b); | 				b = increment(p, b); | ||||||
| 				inex = STRTOG_Inexhi | STRTOG_Underflow; | 				inex = STRTOG_Inexhi | STRTOG_Underflow; | ||||||
|  | #ifndef NO_ERRNO | ||||||
|  | 				errno = ERANGE; | ||||||
|  | #endif | ||||||
| 				} | 				} | ||||||
| 			else if (lostbits) | 			else if (lostbits) | ||||||
| 				inex = STRTOG_Inexlo | STRTOG_Underflow; | 				inex = STRTOG_Inexlo | STRTOG_Underflow; | ||||||
|  | #ifndef NO_ERRNO | ||||||
|  | 				errno = ERANGE; | ||||||
|  | #endif | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	else if (e > fpi->emax) { | 	else if (e > fpi->emax) { | ||||||
| @@ -761,6 +770,9 @@ _strtodg_l (struct _reent *p, const char *s00, char **se, FPI *fpi, Long *exp, | |||||||
| 					rvb->_x[0] = 0; | 					rvb->_x[0] = 0; | ||||||
| 					*exp = emin; | 					*exp = emin; | ||||||
| 					irv = STRTOG_Underflow | STRTOG_Inexlo; | 					irv = STRTOG_Underflow | STRTOG_Inexlo; | ||||||
|  | #ifndef NO_ERRNO | ||||||
|  | 					errno = ERANGE; | ||||||
|  | #endif | ||||||
| 					goto ret; | 					goto ret; | ||||||
| 					} | 					} | ||||||
| 				rvb->_x[0] = rvb->_wds = rvbits = 1; | 				rvb->_x[0] = rvb->_wds = rvbits = 1; | ||||||
| @@ -940,6 +952,9 @@ _strtodg_l (struct _reent *p, const char *s00, char **se, FPI *fpi, Long *exp, | |||||||
| 				rvb->_wds = 0; | 				rvb->_wds = 0; | ||||||
| 				rve = emin; | 				rve = emin; | ||||||
| 				irv = STRTOG_Underflow | STRTOG_Inexlo; | 				irv = STRTOG_Underflow | STRTOG_Inexlo; | ||||||
|  | #ifndef NO_ERRNO | ||||||
|  | 				errno = ERANGE; | ||||||
|  | #endif | ||||||
| 				break; | 				break; | ||||||
| 				} | 				} | ||||||
| 			adj0 = dval(adj) = 1.; | 			adj0 = dval(adj) = 1.; | ||||||
| @@ -1083,12 +1098,18 @@ _strtodg_l (struct _reent *p, const char *s00, char **se, FPI *fpi, Long *exp, | |||||||
| 		if (sudden_underflow) { | 		if (sudden_underflow) { | ||||||
| 			rvb->_wds = 0; | 			rvb->_wds = 0; | ||||||
| 			irv = STRTOG_Underflow | STRTOG_Inexlo; | 			irv = STRTOG_Underflow | STRTOG_Inexlo; | ||||||
|  | #ifndef NO_ERRNO | ||||||
|  | 			errno = ERANGE; | ||||||
|  | #endif | ||||||
| 			} | 			} | ||||||
| 		else  { | 		else  { | ||||||
| 			irv = (irv & ~STRTOG_Retmask) | | 			irv = (irv & ~STRTOG_Retmask) | | ||||||
| 				(rvb->_wds > 0 ? STRTOG_Denormal : STRTOG_Zero); | 				(rvb->_wds > 0 ? STRTOG_Denormal : STRTOG_Zero); | ||||||
| 			if (irv & STRTOG_Inexact) | 			if (irv & STRTOG_Inexact) | ||||||
| 				irv |= STRTOG_Underflow; | 				irv |= STRTOG_Underflow; | ||||||
|  | #ifndef NO_ERRNO | ||||||
|  | 				errno = ERANGE; | ||||||
|  | #endif | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	if (se) | 	if (se) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user