Example #1
0
size_t stream_putdouble(stream_s *stream, long double value, int precision, int flags)
{
	char *string = __format_double(value, flags, precision);
	size_t len = strlen(string);
	stream_putstring(stream, string);
	free(string);
	return len;
}
Example #2
0
static char *__format_double(long double value, int flags, int precision) {
	char *int_part;
	char *dec_part;
	char *string;
	long double i;

	if (isnan(value)) {
		if (flags & FLAG_UPPER) {
			return strdup("NAN");
		}
		else {
			return strdup("nan");
		}
	}

	if (isinf(value)) {
		if (flags & FLAG_UPPER) {
			if (value < 0) {
				return strdup("-INF");
			}
			else {
				if (flags & FLAG_SIGN) {
					return strdup("+INF");
				}
				else {
					return strdup("INF");
				}
			}
		}
		else {
			if (value < 0) {
				return strdup("-inf");
			}
			else {
				if (flags & FLAG_SIGN) {
					return strdup("+inf");
				}
				else {
					return strdup("inf");
				}
			}
		}
	}

	if (flags & FLAG_EXP || (flags & FLAG_MEXP && value > 1000000000)) {
		i = log10l(value);
		value /= powl(10, floorl(i));

		int_part = __format_double(value, flags & ~(FLAG_EXP), precision);
		dec_part = __format_int(i, flags | FLAG_SIGN);

		string = strvcat(int_part, (flags & FLAG_UPPER) ? "E" : "e", dec_part, NULL);

		free(int_part);
		free(dec_part);
	}
	else {
		value = modfl(value, &i);

		if (value > 2000000000) {
			int_part = __format_double_int(i, flags);
		}
		else {
			int_part = __format_int(i, flags);
		}
		dec_part = __format_double_frac(value, flags, precision);

		if (i == 0.0 && value < 0) {
			if (value != 0.0 || flags & FLAG_ALT) {
				string = strvcat("-", int_part, ".", dec_part, NULL);
			}
			else {
				string = strvcat("-", int_part, NULL);
			}
		}
		else {
			if (value != 0.0 || flags & FLAG_ALT) {
				string = strvcat(int_part, ".", dec_part, NULL);
			}
			else {
				string = strdup(int_part);
			}
		}

		free(int_part);
		free(dec_part);
	}

	return string;
}