cake
/
libg1m
Archived
1
0
Fork 0
This repository has been archived on 2024-03-16. You can view files and clone it, but cannot push or open issues or pull requests.
libg1m/include/libg1m/bcd.h

97 lines
3.2 KiB
C

/* *****************************************************************************
* libg1m/bcd.h -- BCD-encoded numbers manipulation.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libg1m.
* libg1m is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libg1m is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libg1m; if not, see <http://www.gnu.org/licenses/>.
*
* BCD are the main number format CASIO uses in its calculators.
* Each semi-byte is a digit going from 0 to 9 (0xA to 0xF aren't used).
* This format has the huge advantage to make 0.1 + 0.2 and 0.3 equal.
*
* The first three digits are the exponent.
* If the exponent is more than 500, then remove 500, and that means the
* number is negative.
* Then you have to remove 100 to have the real exponent.
*
* Before applying these operations, you should check the most significant bit
* of the upper nibble of the first binary-coded digit of the exponent.
* If it is 1, then the number has a complex part. Anyway, always set this
* bit to zero before interpreting the exponent.
*
* The other 15 digits are the mantissa. So the number is: (M ** (E + 1))
* ************************************************************************** */
#ifndef LIBG1M_BCD_H
# define LIBG1M_BCD_H
# ifdef __cplusplus
extern "C" {
# endif
/* Type definition */
typedef struct bcd {
/* the BCD value itself */
unsigned char BCDval[9];
/* some 4-bytes alignment stuff */
unsigned char _align[3];
} g1m_bcd_t;
/* ************************************************************************** */
/* BCD utilities */
/* ************************************************************************** */
/* Arithmetic */
int g1m_bcd_is_nonzero(g1m_bcd_t *bcd);
/* String/BCD */
char *g1m_bcdtoa(g1m_bcd_t *bcd);
/* ************************************************************************** */
/* Inline BCD utilities */
/* ************************************************************************** */
/**
* g1m_bcd_is_negative:
* Quick check.
*
* @arg bcd pointer to the BCD number.
* @return a boolean.
*/
static inline int g1m_bcd_is_negative(g1m_bcd_t *bcd)
{
return (bcd->BCDval[0] >= 0x50);
}
/**
* g1m_bcd_high_bit:
* Quick check.
*
* @arg bcd pointer to the BCD number.
* @return a boolean.
*/
static inline int g1m_bcd_high_bit(g1m_bcd_t *bcd)
{
return (bcd->BCDval[0] & 0x80);
}
/* macros */
# define g1m_bcd_is_positive(B) (!g1m_bcd_is_negative(B))
# define g1m_bcd_is_zero(B) (!g1m_bcd_is_nonzero(B))
# define g1m_bcd_has_complex(B) (g1m_bcd_high_bit(B))
# ifdef __cplusplus
}
# endif
#endif /* LIBG1M_BCD_H */