美文网首页C语言C语言&嵌入式
用纯C11草案标准写高移植性代码例程

用纯C11草案标准写高移植性代码例程

作者: FSS_Sosei | 来源:发表于2019-01-12 21:28 被阅读3次

    2012年写的

    原来放在开源中国社区的

    还是转过来吧

        /*

            <General Utilities>

            Copyright (C) <2012>  <fss.sosei>

            This program is free software: you can redistribute it and/or modify

            it under the terms of the GNU General Public License as published by

            the Free Software Foundation, either version 3 of the License, or

            (at your option) any later version.

            This program 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 General Public License for more details.

            You should have received a copy of the GNU General Public License

            along with this program.  If not, see <http://www.gnu.org/licenses/>.

        */

        #include <stdint.h>

        #include <iso646.h>

        #include <math.h>

        #include <inttypes.h>

        #include <stdio.h>

        #include <stdlib.h>

        #include <float.h>

        #include <tgmath.h>

    #define max(_a, _b) _Generic(sizeof(_a) >= sizeof(_b) ? _a : _b, int8_t: max_i8, \

                                                                     uint8_t: max_ui8, \

                                                                     int16_t: max_i16, \

                                                                     uint16_t: max_ui16, \

                                                                     int32_t: max_i32, \

                                                                     uint32_t: max_ui32, \

                                                                     int64_t: max_i64, \

                                                                     uint64_t: max_ui64, \

                                                                     default: max_i64 \

                                )(_a, _b)

    #define min(_a, _b) _Generic(sizeof(_a) >= sizeof(_b) ? _a : _b, int8_t: min_i8, \

                                                                     uint8_t: min_ui8, \

                                                                     int16_t: min_i16, \

                                                                     uint16_t: min_ui16, \

                                                                     int32_t: min_i32, \

                                                                     uint32_t: min_ui32, \

                                                                     int64_t: min_i64, \

                                                                     uint64_t: min_ui64, \

                                                                     default: min_i64 \

                                )(_a, _b)

    #define read_bit(_source_bits, _source_width, _n) _Generic(_source_bits, uint8_t: read_bit_ui8, \

                                                                             uint16_t: read_bit_ui16, \

                                                                             uint32_t: read_bit_ui32, \

                                                                             uint64_t: read_bit_ui64, \

                                                                             default: read_bit_ui64 \

                                                              )(_source_bits, _source_width, _n)

    #define write_bit(_source_bits, _source_width, _n, _a_bit) _Generic(_source_bits, uint8_t: write_bit_ui8, \

                                                                                      uint16_t: write_bit_ui16, \

                                                                                      uint32_t: write_bit_ui32, \

                                                                                      uint64_t: write_bit_ui64, \

                                                                                      default: write_bit_ui64 \

                                                                       )(_source_bits, _source_width, _n, _a_bit)

    #define xor_bit(_source_bits, _source_width, _n, _a_bit) _Generic(_source_bits, uint8_t: xor_bit_ui8, \

                                                                                    uint16_t: xor_bit_ui16, \

                                                                                    uint32_t: xor_bit_ui32, \

                                                                                    uint64_t: xor_bit_ui64, \

                                                                                    default: xor_bit_ui64 \

                                                                     )(_source_bits, _source_width, _n, _a_bit)

    #define random_round(_x, _rounded_to_exp10) _Generic(_x, float: random_round_f, \

                                                             double: random_round_d, \

                                                             default: random_round_f \

                                                        )(_x, _rounded_to_exp10)

    #define integer_number_to_string(_input_number, _leader_character, _display_width, _numeric_string, _array_len) _Generic(_input_number, int8_t: integer_number_to_string_i8, \

                                                                                                                                            int16_t: integer_number_to_string_i16, \

                                                                                                                                            int32_t: integer_number_to_string_i32, \

                                                                                                                                            default: integer_number_to_string_i32 \

                                                                                                                            )(_input_number, _leader_character, _display_width, _numeric_string, _array_len)

    #define floating_number_to_string(_input_number, _decimal_digits, _numeric_string, _array_len) _Generic(_input_number, float: floating_number_to_string_f, \

                                                                                                                           double: floating_number_to_string_d, \

                                                                                                                           default: floating_number_to_string_f \

                                                                                                           )(_input_number, _decimal_digits, _numeric_string, _array_len)

    inlineint8_t max_i8(int8_t a, int8_t b)

    {

        returna > b ? a : b;

    }

    inlineuint8_t max_ui8(uint8_t a, uint8_t b)

    {

        returna > b ? a : b;

    }

    inlineint16_t max_i16(int16_t a, int16_t b)

    {

        returna > b ? a : b;

    }

    inlineuint16_t max_ui16(uint16_t a, uint16_t b)

    {

        returna > b ? a : b;

    }

    inlineint32_t max_i32(int32_t a, int32_t b)

    {

        returna > b ? a : b;

    }

    inlineuint32_t max_ui32(uint32_t a, uint32_t b)

    {

        returna > b ? a : b;

    }

    inlineint64_t max_i64(int64_t a, int64_t b)

    {

        returna > b ? a : b;

    }

    inlineuint64_t max_ui64(uint64_t a, uint64_t b)

    {

        returna > b ? a : b;

    }

    inlineint8_t min_i8(int8_t a, int8_t b)

    {

        returna < b ? a : b;

    }

    inlineuint8_t min_ui8(uint8_t a, uint8_t b)

    {

        returna < b ? a : b;

    }

    inlineint16_t min_i16(int16_t a, int16_t b)

    {

        returna < b ? a : b;

    }

    inlineuint16_t min_ui16(uint16_t a, uint16_t b)

    {

        returna < b ? a : b;

    }

    inlineint32_t min_i32(int32_t a, int32_t b)

    {

        returna < b ? a : b;

    }

    inlineuint32_t min_ui32(uint32_t a, uint32_t b)

    {

        returna < b ? a : b;

    }

    inlineint64_t min_i64(int64_t a, int64_t b)

    {

        returna < b ? a : b;

    }

    inlineuint64_t min_ui64(uint64_t a, uint64_t b)

    {

        returna < b ? a : b;

    }

    uint8_t read_bit_ui8(uint8_t source_bits, uint_fast8_t source_width, uint_fast8_t n)  //Lowest order is 0

    {

        constuint_fast8_t MAXIMUM_WIDTH_BIT = 8;

        if((source_bits >> source_width) not_eq 0)

        {

            returnsource_bits;

        }

        if(source_width > MAXIMUM_WIDTH_BIT)

        {

            returnsource_bits;

        }

        if(n >= source_width)

        {

            returnsource_bits;

        }

        return(source_bits >> n) bitand ((uint8_t)0x01);

    }

    uint16_t read_bit_ui16(uint16_t source_bits, uint_fast8_t source_width, uint_fast8_t n)  //Lowest order is 0

    {

        constuint_fast8_t MAXIMUM_WIDTH_BIT = 16;

        if((source_bits >> source_width) not_eq 0)

        {

            returnsource_bits;

        }

        if(source_width > MAXIMUM_WIDTH_BIT)

        {

            returnsource_bits;

        }

        if(n >= source_width)

        {

            returnsource_bits;

        }

        return(source_bits >> n) bitand ((uint16_t)0x01);

    }

    uint32_t read_bit_ui32(uint32_t source_bits, uint_fast8_t source_width, uint_fast8_t n)  //Lowest order is 0

    {

        constuint_fast8_t MAXIMUM_WIDTH_BIT = 32;

        if((source_bits >> source_width) not_eq 0)

        {

            returnsource_bits;

        }

        if(source_width > MAXIMUM_WIDTH_BIT)

        {

            returnsource_bits;

        }

        if(n >= source_width)

        {

            returnsource_bits;

        }

        return(source_bits >> n) bitand ((uint32_t)0x01);

    }

    uint64_t read_bit_ui64(uint64_t source_bits, uint_fast8_t source_width, uint_fast8_t n)  //Lowest order is 0

    {

        constuint_fast8_t MAXIMUM_WIDTH_BIT = 64;

        if((source_bits >> source_width) not_eq 0)

        {

            returnsource_bits;

        }

        if(source_width > MAXIMUM_WIDTH_BIT)

        {

            returnsource_bits;

        }

        if(n >= source_width)

        {

            returnsource_bits;

        }

        return(source_bits >> n) bitand ((uint64_t)0x01);

    }

    uint8_t write_bit_ui8(uint8_t source_bits, uint_fast8_t source_width, uint_fast8_t n, uint_fast8_t a_bit)  //Lowest order is 0

    {

        constuint_fast8_t MAXIMUM_WIDTH_BIT = 8;

        if((source_bits >> source_width) not_eq 0)

        {

            returnsource_bits;

        }

        if(source_width > MAXIMUM_WIDTH_BIT)

        {

            returnsource_bits;

        }

        if(n >= source_width)

        {

            returnsource_bits;

        }

        if((a_bit >> 1) not_eq 0)

        {

            returnsource_bits;

        }

        (a_bit == 0) ? (source_bits and_eq (compl(((uint8_t)0x01) << n))) : (source_bits or_eq (((uint8_t)0x01) << n));

        returnsource_bits;

    }

    uint16_t write_bit_ui16(uint16_t source_bits, uint_fast8_t source_width, uint_fast8_t n, uint_fast8_t a_bit)  //Lowest order is 0

    {

        constuint_fast8_t MAXIMUM_WIDTH_BIT = 16;

        if((source_bits >> source_width) not_eq 0)

        {

            returnsource_bits;

        }

        if(source_width > MAXIMUM_WIDTH_BIT)

        {

            returnsource_bits;

        }

        if(n >= source_width)

        {

            returnsource_bits;

        }

        if((a_bit >> 1) not_eq 0)

        {

            returnsource_bits;

        }

        (a_bit == 0) ? (source_bits and_eq (compl(((uint16_t)0x01) << n))) : (source_bits or_eq (((uint16_t)0x01) << n));

        returnsource_bits;

    }

    uint32_t write_bit_ui32(uint32_t source_bits, uint_fast8_t source_width, uint_fast8_t n, uint_fast8_t a_bit)  //Lowest order is 0

    {

        constuint_fast8_t MAXIMUM_WIDTH_BIT = 32;

        if((source_bits >> source_width) not_eq 0)

        {

            returnsource_bits;

        }

        if(source_width > MAXIMUM_WIDTH_BIT)

        {

            returnsource_bits;

        }

        if(n >= source_width)

        {

            returnsource_bits;

        }

        if((a_bit >> 1) not_eq 0)

        {

            returnsource_bits;

        }

        (a_bit == 0) ? (source_bits and_eq (compl(((uint32_t)0x01) << n))) : (source_bits or_eq (((uint32_t)0x01) << n));

        returnsource_bits;

    }

    uint64_t write_bit_ui64(uint64_t source_bits, uint_fast8_t source_width, uint_fast8_t n, uint_fast8_t a_bit)  //Lowest order is 0

    {

        constuint_fast8_t MAXIMUM_WIDTH_BIT = 64;

        if((source_bits >> source_width) not_eq 0)

        {

            returnsource_bits;

        }

        if(source_width > MAXIMUM_WIDTH_BIT)

        {

            returnsource_bits;

        }

        if(n >= source_width)

        {

            returnsource_bits;

        }

        if((a_bit >> 1) not_eq 0)

        {

            returnsource_bits;

        }

        (a_bit == 0) ? (source_bits and_eq (compl(((uint64_t)0x01) << n))) : (source_bits or_eq (((uint64_t)0x01) << n));

        returnsource_bits;

    }

    uint8_t xor_bit_ui8(uint8_t source_bits, uint_fast8_t source_width, uint_fast8_t n, uint_fast8_t a_bit)  //Lowest order is 0

    {

        constuint_fast8_t MAXIMUM_WIDTH_BIT = 8;

        if((source_bits >> source_width) not_eq 0)

        {

            returnsource_bits;

        }

        if(source_width > MAXIMUM_WIDTH_BIT)

        {

            returnsource_bits;

        }

        if(n >= source_width)

        {

            returnsource_bits;

        }

        if((a_bit >> 1) not_eq 0)

        {

            returnsource_bits;

        }

        returnsource_bits xor (((uint8_t)a_bit) << n);

    }

    uint16_t xor_bit_ui16(uint16_t source_bits, uint_fast8_t source_width, uint_fast8_t n, uint_fast8_t a_bit)  //Lowest order is 0

    {

        constuint_fast8_t MAXIMUM_WIDTH_BIT = 16;

        if((source_bits >> source_width) not_eq 0)

        {

            returnsource_bits;

        }

        if(source_width > MAXIMUM_WIDTH_BIT)

        {

            returnsource_bits;

        }

        if(n >= source_width)

        {

            returnsource_bits;

        }

        if((a_bit >> 1) not_eq 0)

        {

            returnsource_bits;

        }

        returnsource_bits xor (((uint16_t)a_bit) << n);

    }

    uint32_t xor_bit_ui32(uint32_t source_bits, uint_fast8_t source_width, uint_fast8_t n, uint_fast8_t a_bit)  //Lowest order is 0

    {

        constuint_fast8_t MAXIMUM_WIDTH_BIT = 32;

        if((source_bits >> source_width) not_eq 0)

        {

            returnsource_bits;

        }

        if(source_width > MAXIMUM_WIDTH_BIT)

        {

            returnsource_bits;

        }

        if(n >= source_width)

        {

            returnsource_bits;

        }

        if((a_bit >> 1) not_eq 0)

        {

            returnsource_bits;

        }

        returnsource_bits xor (((uint32_t)a_bit) << n);

    }

    uint64_t xor_bit_ui64(uint64_t source_bits, uint_fast8_t source_width, uint_fast8_t n, uint_fast8_t a_bit)  //Lowest order is 0

    {

        constuint_fast8_t MAXIMUM_WIDTH_BIT = 64;

        if((source_bits >> source_width) not_eq 0)

        {

            returnsource_bits;

        }

        if(source_width > MAXIMUM_WIDTH_BIT)

        {

            returnsource_bits;

        }

        if(n >= source_width)

        {

            returnsource_bits;

        }

        if((a_bit >> 1) not_eq 0)

        {

            returnsource_bits;

        }

        returnsource_bits xor (((uint64_t)a_bit) << n);

    }

    floatrandom_round_f(floatx, int_fast8_t rounded_to_exp10)

    {

        constuint_fast8_t MAX_SIGNIFICANT_FIGURES = FLT_DIG - 1;

        if(not isfinite(x))

        {

            returnx;

        }

        floatabsolute_value = fabs(x);

        if((floor(log10(absolute_value)) - rounded_to_exp10) >= MAX_SIGNIFICANT_FIGURES)

        {

            returnx;

        }

        floatinteger_part, decimal_part;

        decimal_part = modff(absolute_value * pow(10, -rounded_to_exp10), &integer_part);

        if(decimal_part > 0.5)

        {

            integer_part += 1;

        }

        else

        {

            if(decimal_part == 0.5)

            {

                integer_part += rand() % 2;

            }

        }

        returncopysign((integer_part + 0.1) * pow(10, rounded_to_exp10), x);

    }

    doublerandom_round_d(doublex, int_fast8_t rounded_to_exp10)

    {

        constuint_fast8_t MAX_SIGNIFICANT_FIGURES = DBL_DIG - 1;

        if(not isfinite(x))

        {

            returnx;

        }

        doubleabsolute_value = fabs(x);

        if((floor(log10(absolute_value)) - rounded_to_exp10) >= MAX_SIGNIFICANT_FIGURES)

        {

            returnx;

        }

        doubleinteger_part, decimal_part;

        decimal_part = modf(absolute_value * pow(10, -rounded_to_exp10), &integer_part);

        if(decimal_part > 0.5)

        {

            integer_part += 1;

        }

        else

        {

            if(decimal_part == 0.5)

            {

                integer_part += rand() % 2;

            }

        }

        returncopysign((integer_part + 0.1) * pow(10, rounded_to_exp10), x);

    }

    uint_fast8_t integer_number_to_string_i8(int8_t input_number, charleader_character, uint_fast8_t display_width, charnumeric_string[], uint_fast8_t array_len)  //input_number range is INT8_MAX to INT8_MIN. Returns the numeric string length.

    {

        constuint_fast8_t INTERMEDIATE_MAX_WIDTH = 1 + (floor(log10(-((float)INT8_MIN))) + 1);  //sign + Max significant figures

        charintermediate_string[INTERMEDIATE_MAX_WIDTH + 1];

        if(leader_character < '\x0')

        {

            return0;

        }

        if(display_width >= array_len)

        {

            return0;

        }

        if(array_len <= 1)

        {

            return0;

        }

        int_fast8_t intermediate_len = sprintf(intermediate_string, "%-"PRIi8, input_number);

        if(intermediate_len > display_width)

        {

            return0;

        }

        int_fast8_t i = 0;

        int_fast8_t n = display_width - (intermediate_len + 1);

        if(isgraph(leader_character))

        {

            while(i <= n)

            {

                numeric_string[i] = leader_character;

                ++i;

            }

        }

        n = i + intermediate_len;

        int_fast8_t j = 0;

        while(i <= n)

        {

            numeric_string[i] = intermediate_string[j];

            ++i;

            ++j;

        }

        i -= 1;

        returni;  //Returns the numeric string length

    }

    uint_fast8_t integer_number_to_string_i16(int16_t input_number, charleader_character, uint_fast8_t display_width, charnumeric_string[], uint_fast8_t array_len)  //input_number range is INT16_MAX to INT16_MIN. Returns the numeric string length.

    {

        constuint_fast8_t INTERMEDIATE_MAX_WIDTH = 1 + (floor(log10(-((float)INT16_MIN))) + 1);  //sign + Max significant figures

        charintermediate_string[INTERMEDIATE_MAX_WIDTH + 1];

        if(leader_character < '\x0')

        {

            return0;

        }

        if(display_width >= array_len)

        {

            return0;

        }

        if(array_len <= 1)

        {

            return0;

        }

        int_fast8_t intermediate_len = sprintf(intermediate_string, "%-"PRIi16, input_number);

        if(intermediate_len > display_width)

        {

            return0;

        }

        int_fast8_t i = 0;

        int_fast8_t n = display_width - (intermediate_len + 1);

        if(isgraph(leader_character))

        {

            while(i <= n)

            {

                numeric_string[i] = leader_character;

                ++i;

            }

        }

        n = i + intermediate_len;

        int_fast8_t j = 0;

        while(i <= n)

        {

            numeric_string[i] = intermediate_string[j];

            ++i;

            ++j;

        }

        i -= 1;

        returni;  //Returns the numeric string length

    }

    uint_fast8_t integer_number_to_string_i32(int32_t input_number, charleader_character, uint_fast8_t display_width, charnumeric_string[], uint_fast8_t array_len)  //input_number range is INT32_MAX to INT32_MIN. Returns the numeric string length.

    {

        constuint_fast8_t INTERMEDIATE_MAX_WIDTH = 1 + (floor(log10(-((double)INT32_MIN))) + 1);  //sign + Max significant figures

        charintermediate_string[INTERMEDIATE_MAX_WIDTH + 1];

        if(leader_character < '\x0')

        {

            return0;

        }

        if(display_width >= array_len)

        {

            return0;

        }

        if(array_len <= 1)

        {

            return0;

        }

        int_fast8_t intermediate_len = sprintf(intermediate_string, "%-"PRIi32, input_number);

        if(intermediate_len > display_width)

        {

            return0;

        }

        int_fast8_t i = 0;

        int_fast8_t n = display_width - (intermediate_len + 1);

        if(isgraph(leader_character))

        {

            while(i <= n)

            {

                numeric_string[i] = leader_character;

                ++i;

            }

        }

        n = i + intermediate_len;

        int_fast8_t j = 0;

        while(i <= n)

        {

            numeric_string[i] = intermediate_string[j];

            ++i;

            ++j;

        }

        i -= 1;

        returni;  //Returns the numeric string length

    }

    uint_fast8_t floating_number_to_string_f(floatinput_number, uint_fast8_t decimal_digits, charnumeric_string[], uint_fast8_t array_len)  //input_number range is (pow(10, MAX_SIGNIFICANT_FIGURES) - 1) to pow(10, -MIN_DECIMAL). Returns the numeric string length. The random roundoff, pay attention to the random number seed.

    {

        constuint_fast8_t MAX_SIGNIFICANT_FIGURES = FLT_DIG - 1;

        constuint_fast8_t MIN_DECIMAL = MAX_SIGNIFICANT_FIGURES + 1;

        chartemp_string[1 + (decimal_digits == 0 ? MAX_SIGNIFICANT_FIGURES : max((MAX_SIGNIFICANT_FIGURES + 1), (1 + 1 + MIN_DECIMAL))) + 1];  //a sign + (decimal_digits == 0 ? MAX_SIGNIFICANT_FIGURES : max((MAX_SIGNIFICANT_FIGURES + a decimal), (a zero + a decimal + MIN_DECIMAL))) + '\x0'

        floatabsolute_value;

        floatnum_exp10;

        if(not isfinite(input_number))

        {

            return0;

        }

        if(decimal_digits > MIN_DECIMAL)

        {

            return0;

        }

        absolute_value = fabs(input_number);

        num_exp10 = floor(log10(absolute_value));

        if(num_exp10 >= MAX_SIGNIFICANT_FIGURES)

        {  //Value ultra range error

            return0;

        }

        floatnum_tail_exp10 = fmax((num_exp10 + 1 - MAX_SIGNIFICANT_FIGURES), (-((int_fast8_t)decimal_digits)));  //Plus integer part

        input_number = random_round_d(absolute_value, lround(num_tail_exp10));

        absolute_value = fabs(input_number);

        num_exp10 = floor(log10(absolute_value));

        int_fast8_t num_int_exp10 = lround(num_exp10);

        if(num_int_exp10 >= MAX_SIGNIFICANT_FIGURES)

        {  //Value ultra range error

            return0;

        }

        num_tail_exp10 = fmax((num_exp10 + 1 - MAX_SIGNIFICANT_FIGURES), (-((int_fast8_t)decimal_digits)));  //Plus integer part

        int_fast8_t num_int_tail_exp10 = lround(num_tail_exp10);

        if(num_int_tail_exp10 > num_int_exp10)

        {

            num_exp10 = num_tail_exp10;

            num_int_exp10 = num_int_tail_exp10;

        }

        uint_fast8_t num_count = num_int_exp10 - num_int_tail_exp10 + 1;

        floatintermediate_number = absolute_value * pow(10, -num_exp10);

        floatdigital_character[num_count];

        for(int_fast8_t i = 0; i < num_count; ++i)

        {

            intermediate_number = modff(intermediate_number, &digital_character[i]) * 10;

        }

        int_fast8_t i = 0;

        uint_fast8_t n;

        if((input_number < 0 ? 1 : 0) == 1)

        {

            temp_string[i] = '-'; ++i;

        }

        int_fast8_t j = 0;

        if(num_int_exp10 >= 0)

        {

            n = i + num_int_exp10;

            while(i <= n)

            {

                temp_string[i] = (char)(lround(digital_character[j]) + 0x30);  //0x30 == '0'

                ++i;

                ++j;

            }

            if((num_int_tail_exp10 < 0 ? 1 : 0) == 1)

            {

                temp_string[i] = '.'; ++i;

            }

            n = i + abs(num_int_tail_exp10);

            while(i < n)

            {

                temp_string[i] = (char)(lround(digital_character[j]) + 0x30);  //0x30 == '0'

                ++i;

                ++j;

            }

        }

        else

        {

            temp_string[i] = '0'; ++i;

            temp_string[i] = '.'; ++i;

            n = i + (-1 - num_int_exp10);

            while(i < n)

            {

                temp_string[i] = '0'; ++i;

            }

            n = i + (num_int_exp10 - num_int_tail_exp10);

            while(i <= n)

            {

                temp_string[i] = (char)(lround(digital_character[j]) + 0x30);  //0x30 == '0'

                ++i;

                ++j;

            }

        }

        temp_string[i] = '\x0';

        n = i;

        if((n + 1) > array_len)

        {

            return0;

        }

        for(i=0; i <= n; ++i)

        {

            numeric_string[i] = temp_string[i];

        }

        returnn;  //Returns the numeric string length

    }

    uint_fast8_t floating_number_to_string_d(doubleinput_number, uint_fast8_t decimal_digits, charnumeric_string[], uint_fast8_t array_len)  //input_number range is (pow(10, MAX_SIGNIFICANT_FIGURES) - 1) to pow(10, -MIN_DECIMAL). Returns the numeric string length. The random roundoff, pay attention to the random number seed.

    {

        constuint_fast8_t MAX_SIGNIFICANT_FIGURES = DBL_DIG - 1;

        constuint_fast8_t MIN_DECIMAL = MAX_SIGNIFICANT_FIGURES + 1;

        chartemp_string[1 + (decimal_digits == 0 ? MAX_SIGNIFICANT_FIGURES : max((MAX_SIGNIFICANT_FIGURES + 1), (1 + 1 + MIN_DECIMAL))) + 1];  //a sign + (decimal_digits == 0 ? MAX_SIGNIFICANT_FIGURES : max((MAX_SIGNIFICANT_FIGURES + a decimal), (a zero + a decimal + MIN_DECIMAL))) + '\x0'

        doubleabsolute_value;

        doublenum_exp10;

        if(not isfinite(input_number))

        {

            return0;

        }

        if(decimal_digits > MIN_DECIMAL)

        {

            return0;

        }

        absolute_value = fabs(input_number);

        num_exp10 = floor(log10(absolute_value));

        if(num_exp10 >= MAX_SIGNIFICANT_FIGURES)

        {  //Value ultra range error

            return0;

        }

        doublenum_tail_exp10 = fmax((num_exp10 + 1 - MAX_SIGNIFICANT_FIGURES), (-((int_fast8_t)decimal_digits)));  //Plus integer part

        input_number = random_round_d(absolute_value, lround(num_tail_exp10));

        absolute_value = fabs(input_number);

        num_exp10 = floor(log10(absolute_value));

        int_fast8_t num_int_exp10 = lround(num_exp10);

        if(num_int_exp10 >= MAX_SIGNIFICANT_FIGURES)

        {  //Value ultra range error

            return0;

        }

        num_tail_exp10 = fmax((num_exp10 + 1 - MAX_SIGNIFICANT_FIGURES), (-((int_fast8_t)decimal_digits)));  //Plus integer part

        int_fast8_t num_int_tail_exp10 = lround(num_tail_exp10);

        if(num_int_tail_exp10 > num_int_exp10)

        {

            num_exp10 = num_tail_exp10;

            num_int_exp10 = num_int_tail_exp10;

        }

        uint_fast8_t num_count = num_int_exp10 - num_int_tail_exp10 + 1;

        doubleintermediate_number = absolute_value * pow(10, -num_exp10);

        doubledigital_character[num_count];

        for(int_fast8_t i = 0; i < num_count; ++i)

        {

            intermediate_number = modf(intermediate_number, &digital_character[i]) * 10;

        }

        int_fast8_t i = 0;

        uint_fast8_t n;

        if((input_number < 0 ? 1 : 0) == 1)

        {

            temp_string[i] = '-'; ++i;

        }

        int_fast8_t j = 0;

        if(num_int_exp10 >= 0)

        {

            n = i + num_int_exp10;

            while(i <= n)

            {

                temp_string[i] = (char)(lround(digital_character[j]) + 0x30);  //0x30 == '0'

                ++i;

                ++j;

            }

            if((num_int_tail_exp10 < 0 ? 1 : 0) == 1)

            {

                temp_string[i] = '.'; ++i;

            }

            n = i + abs(num_int_tail_exp10);

            while(i < n)

            {

                temp_string[i] = (char)(lround(digital_character[j]) + 0x30);  //0x30 == '0'

                ++i;

                ++j;

            }

        }

        else

        {

            temp_string[i] = '0'; ++i;

            temp_string[i] = '.'; ++i;

            n = i + (-1 - num_int_exp10);

            while(i < n)

            {

                temp_string[i] = '0'; ++i;

            }

            n = i + (num_int_exp10 - num_int_tail_exp10);

            while(i <= n)

            {

                temp_string[i] = (char)(lround(digital_character[j]) + 0x30);  //0x30 == '0'

                ++i;

                ++j;

            }

        }

        temp_string[i] = '\x0';

        n = i;

        if((n + 1) > array_len)

        {

            return0;

        }

        for(i=0; i <= n; ++i)

        {

            numeric_string[i] = temp_string[i];

        }

        returnn;  //Returns the numeric string length

    }

    相关文章

      网友评论

        本文标题:用纯C11草案标准写高移植性代码例程

        本文链接:https://www.haomeiwen.com/subject/wyfhdqtx.html