/*---------------------------------------------------------------------------
 *
 * Common routines for Ryu floating-point output.
 *
 * Portions Copyright (c) 2018-2021, PostgreSQL Global Development Group
 *
 * IDENTIFICATION
 *	  src/common/ryu_common.h
 *
 * This is a modification of code taken from github.com/ulfjack/ryu under the
 * terms of the Boost license (not the Apache license). The original copyright
 * notice follows:
 *
 * Copyright 2018 Ulf Adams
 *
 * The contents of this file may be used under the terms of the Apache
 * License, Version 2.0.
 *
 *     (See accompanying file LICENSE-Apache or copy at
 *      http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Alternatively, the contents of this file may be used under the terms of the
 * Boost Software License, Version 1.0.
 *
 *     (See accompanying file LICENSE-Boost or copy at
 *      https://www.boost.org/LICENSE_1_0.txt)
 *
 * Unless required by applicable law or agreed to in writing, this software is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.
 *
 *---------------------------------------------------------------------------
 */
#ifndef RYU_COMMON_H
#define RYU_COMMON_H

/*
 * Upstream Ryu's output is always the shortest possible. But we adjust that
 * slightly to improve portability: we avoid outputting the exact midpoint
 * value between two representable floats, since that relies on the reader
 * getting the round-to-even rule correct, which seems to be the common
 * failure mode.
 *
 * Defining this to 1 would restore the upstream behavior.
 */
#define STRICTLY_SHORTEST 0

#if SIZEOF_SIZE_T < 8
#define RYU_32_BIT_PLATFORM
#endif

/*  Returns e == 0 ? 1 : ceil(log_2(5^e)). */
static inline uint32
pow5bits(const int32 e)
{
	/*
	 * This approximation works up to the point that the multiplication
	 * overflows at e = 3529.
	 *
	 * If the multiplication were done in 64 bits, it would fail at 5^4004
	 * which is just greater than 2^9297.
	 */
	Assert(e >= 0);
	Assert(e <= 3528);
	return ((((uint32) e) * 1217359) >> 19) + 1;
}

/*  Returns floor(log_10(2^e)). */
static inline int32
log10Pow2(const int32 e)
{
	/*
	 * The first value this approximation fails for is 2^1651 which is just
	 * greater than 10^297.
	 */
	Assert(e >= 0);
	Assert(e <= 1650);
	return (int32) ((((uint32) e) * 78913) >> 18);
}

/*  Returns floor(log_10(5^e)). */
static inline int32
log10Pow5(const int32 e)
{
	/*
	 * The first value this approximation fails for is 5^2621 which is just
	 * greater than 10^1832.
	 */
	Assert(e >= 0);
	Assert(e <= 2620);
	return (int32) ((((uint32) e) * 732923) >> 20);
}

static inline int
copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa)
{
	if (mantissa)
	{
		memcpy(result, "NaN", 3);
		return 3;
	}
	if (sign)
	{
		result[0] = '-';
	}
	if (exponent)
	{
		memcpy(result + sign, "Infinity", 8);
		return sign + 8;
	}
	result[sign] = '0';
	return sign + 1;
}

static inline uint32
float_to_bits(const float f)
{
	uint32		bits = 0;

	memcpy(&bits, &f, sizeof(float));
	return bits;
}

static inline uint64
double_to_bits(const double d)
{
	uint64		bits = 0;

	memcpy(&bits, &d, sizeof(double));
	return bits;
}

#endif							/* RYU_COMMON_H */
