%% options copyright owner = Dirk Krause copyright year = 2017-xxxx SPDX-License-Identifier: BSD-3-Clause %% header /** @file dk4mao8dns.h Print double without scientific notation. The dk4ma_write_c8_double_no_sci_to_stream() function is intended to write coordinates to PDF, PS and EPS output. In contrast to the dk4c8dbl_double_to_stream() function from the dk4c8dbl this function uses parameter eps to print 0 instead of very small absolute values. This module is in the libdk4c library, not libdk4maio8d, as it uses the dk4_stream_t data type and related functions. */ #ifndef DK4CONF_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4conf.h" #else #include #endif #endif #ifndef DK4TYPES_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4types.h" #else #include #endif #endif #ifndef DK4ERROR_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4error.h" #else #include #endif #endif #ifndef DK4STRM_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4strm.h" #else #include #endif #endif #ifndef STDLIB_H_INCLUDED #include #define STDLIB_H_INCLUDED 1 #endif #ifdef __cplusplus extern "C" { #endif /** Write a double value stored in a buffer to a stream, avoid scientific notation. @param strm Stream to write to. @param buf Buffer containing string representation of double value. The buffer contents is modified and probably damaged during operation. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if strm or buf is NULL, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed, - DK4_E_MATH_OVERFLOW
if the exponent is out of range for integer values,
- DK4_E_SYNTAX
if input contains invalid characters. */ int dk4ma_write_c8_double_string_no_sci_to_stream( dk4_stream_t *strm, char *buf, dk4_er_t *erp ); /** Write double value to stream, avoid scientific notation. @param strm Stream to write to. @param v Value to write. @param eps Epsilon (values below epsilon are written as 0). @param ex Flag: Use exact representation. @param min Minimize text representation. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if strm is NULL. - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed, - DK4_E_MATH_OVERFLOW
if the exponent is out of range for integer values,
- DK4_E_SYNTAX
if input contains invalid characters. */ int dk4ma_write_c8_double_no_sci_to_stream( dk4_stream_t *strm, double v, double eps, int ex, int min, dk4_er_t *erp ); #ifdef __cplusplus } #endif /* vim: set ai sw=4 ts=4 : */ %% module #include "dk4conf.h" #ifndef DK4MAO8DNS_H_INCLUDED #include "dk4mao8dns.h" #endif #if DK4_HAVE_STRING_H #ifndef STRING_H_INCLUDED #include #define STRING_H_INCLUDED 1 #endif #endif #if DK4_HAVE_MATH_H #ifndef MATH_H_INCLUDED #if DK4_ON_WINDOWS #ifndef _USE_MATH_DEFINES #define _USE_MATH_DEFINES 1 #endif #endif #include #define MATH_H_INCLUDED 1 #endif #endif #ifndef DK4MAO8DBL_H_INCLUDED #include "dk4mao8dbl.h" #endif #ifndef DK4MAI8DDI_H_INCLUDED #include "dk4mai8ddi.h" #endif #ifndef DK4STR8_H_INCLUDED #include "dk4str8.h" #endif #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif $!trace-include int dk4ma_write_c8_double_string_no_sci_to_stream( dk4_stream_t *strm, char *buf, dk4_er_t *erp ) { char *ptrex = NULL; /* Start of exponent */ char *ptrdd = NULL; /* Decimal dot */ char *ptrout = NULL; /* Character to output */ const char *endptr = NULL; /* First unusable exponent character */ dk4_im_t dotpos = (dk4_im_t)0L; /* Dot position */ dk4_im_t expon = (dk4_im_t)0L; /* Exponent */ dk4_im_t i = (dk4_im_t)0L; /* Running index */ int isneg = 0; /* Flag: Negative value */ int res = 0; /* Conversion result */ int back = 0; /* Result */ $? "+ dk4ma_write_c8_double_string_no_sci_to_stream" #if DK4_USE_ASSERT assert(NULL != strm); assert(NULL != buf); #endif if ((NULL != strm) && (NULL != buf)) { back = 1; if ('-' == *buf) { $? ". negative" isneg = 1; buf++; } #if TRACE_DEBUG else { $? ". not negative" } #endif /* Find exponent */ ptrex = strchr(buf, 'e'); if (NULL == ptrex) { ptrex = strchr(buf, 'E'); } if (NULL != ptrex) { *(ptrex++) = '\0'; $? ". exponent=\"%s\"", ptrex if ('+' == *ptrex) { ptrex++; } res = dk4ma_input_c8_dec_dk4_im_t(&expon, ptrex, &endptr, 1, erp); if (0 == res) { expon = (dk4_im_t)0L; back = 0; } $? ". exponent = %d", (int)expon } #if TRACE_DEBUG else { $? ". no exponent" } #endif /* Find decimal dot */ ptrdd = strchr(buf, '.'); if (NULL != ptrdd) { $? ". have decimal dot" *ptrdd = '\0'; dotpos = strlen(buf); dk4str8_cpy_to_left(ptrdd, &(ptrdd[1])); } else { $? ". no decimal dot" dotpos = strlen(buf); } /* Calculate dot position from original position and exponent */ dotpos += expon; $? ". dot position = %d", (int)dotpos /* Write leading zero(s) */ if ((dk4_im_t)0L >= dotpos) { $? ". leading zeros" if (0 != isneg) { if (0 == dk4stream_write_byte(strm, '-', erp)) { back = 0; } isneg = 0; } if (0 == dk4stream_write_byte(strm, '0', erp)) { back = 0; } if (0 == dk4stream_write_byte(strm, '.', erp)) { back = 0; } i = dotpos; while ((dk4_im_t)0L > i++) { if (0 == dk4stream_write_byte(strm, '0', erp)) { back = 0; } } } #if TRACE_DEBUG else { $? ". no leading zeros" } #endif /* Write digits from buffer */ if (0 != isneg) { $? ". negative sign" if (0 == dk4stream_write_byte(strm, '-', erp)) { back = 0; } } #if TRACE_DEBUG else { $? ". no negative sign" } #endif i = (dk4_im_t)0L; ptrout = buf; while ('\0' != *ptrout) { $? ". character %c", *ptrout $? ". dotpos=%d i=%d", (int)dotpos, (int)i if ((dotpos == i) && ((dk4_im_t)0L != dotpos)) { $? ". must write dot" if (0 == dk4stream_write_byte(strm, '.', erp)) { back = 0; $? "! write error (dot)" } } $? ". going to write character" if (0 == dk4stream_write_byte(strm, *(ptrout++), erp)) { back = 0; $? "! write error (character)" } $? ". character was written" i++; } /* Append trailing zero(s) */ $? ". appending trailing zeros i=%d dotpos=%d", (int)i, (int)dotpos while (i++ < dotpos) { if (0 == dk4stream_write_byte(strm, '0', erp)) { back = 0; $? "! write error (trailing zero)" } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } $? "- dk4ma_write_c8_double_string_no_sci_to_stream %d", back return back; } int dk4ma_write_c8_double_no_sci_to_stream( dk4_stream_t *strm, double v, double eps, int ex, int min, dk4_er_t *erp ) { char buf[16*sizeof(double)]; size_t szbuf = sizeof(buf); int back = 0; $? "+ dk4ma_write_c8_double_no_sci_to_stream %g", v #if DK4_USE_ASSERT assert(NULL != strm); #endif if (NULL != strm) { if (fabs(v) < eps) { $? ". 0" back = dk4stream_write_byte(strm, '0', erp); } else { $? ". not 0" if (0 != dk4ma_write_c8_double(buf, szbuf, v, ex, min, erp)) { $? ". buf=\"%s\"", buf back = dk4ma_write_c8_double_string_no_sci_to_stream( strm, buf, erp ); } #if TRACE_DEBUG else { $? "! dk4ma_write_c8_double" } #endif } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } $? "- dk4ma_write_c8_double_no_sci_to_stream %d", back return back; } /* vim: set ai sw=4 ts=4 : */