#include "float.h"




//定义浮点数组 最大数组长度
#define StrExtFloat_flen 64
//定义最大字符串长度
#define StrExtFloat_slen 512

/**
 * @brief 多个浮点串转换, 确保不溢出
 * @param [in] num 
 * @param [in] Str 
 * 
 * @details 加入负数功能, 支持空格分开，多个空格
 *  usage：
 *  char Str[100]="235.654hjfv92.88u98fj3wjf09w43f0f3f963.369";
 * 	float num[StrExtFloat_flen] = {0.};
 *  StrExtFloat(num,Str);
 */
void StrExtFloat(float *num,char* Str)
{
	//遍历深度
	int Fflag = 0;
	//数字个数
	int Fnum = 0;
	char num_start = 0,num_point = 0;
    float NorP = 1;  /* 正数  负数 */
	//遍历到字符串尾部
	while ( *Str != '\0' )
	{	
		Fflag++;
		//防止查询超过边界
		if(Fflag>StrExtFloat_slen)
			break;
		//判断是不是数字
        if( *Str == '-' )
        {
            NorP = -1;
        }
		else if(*Str >='0' && *Str <= '9')
		{
			//printf("%c",*Str);
			//判断数字存在
			num_start = 1;
			//判断是否存在小数点
			if(num_point >= 1)
			{
				num_point++;
				//当前小数部分的数值
				float fpoint = *Str - '0';
				for(int i = 1;i<num_point;i++)
				{
					fpoint = fpoint/10.;
				}
				//加入小数部分
				num[Fnum+1] = num[Fnum+1] + fpoint;
			}
			else
			{
				//加入整数部分
				num[Fnum+1] = num[Fnum+1]*10+(*Str - '0');
			}
		}
		else if(*Str == '.') //判断为小数点
		{
			if(num_start==1)//发现存在小数点
			{
				num_point=1;
			}
		}
		else //判断为其他字符
		{
			if (num_start == 1)
			{
                num[Fnum+1] = num[Fnum+1] * NorP;
				Fnum++;//统计个数加一
                NorP = 1;
			}
			//清空字符统计与小数点统计
			num_start = 0;
			num_point = 0;
		}
		//指针移动
		*(Str++);
	}
	//如果不是以字符结尾
	if (num_start == 1)
	{
		Fnum++;//统计个数加一
	}
	//放入提取到的数字个数
	num[0] = Fnum;
}


/**
 * @brief 单个浮点串  指针传值
 * @param [in] num 
 * @param [in] Str 
 * 
 * @details 
 * 	char Str2[100]="235.654";
 *  float *pFnum = (float*)malloc(sizeof(float));
 *  Str2Float(pFnum, Str2);
 *  printf(" f HEX  %08X\r\n", (uint32_t *) &f);
 */
void Str2Float(float *num, char* Str)
{
	//遍历深度
	int Fflag = 0;
	//数字个数
	int Fnum = 0;
	char num_start = 0,num_point = 0;
    float NorP = 1;  /* 正数  负数 */
    *num = 0.0;
	//遍历到字符串尾部
	while ( *Str != '\0' )
	{	
		Fflag++;
		// //防止查询超过边界
		// if(Fflag>StrExtFloat_slen)
		// 	break;
		//判断是不是数字
        if( *Str == '-' )
        {
            NorP = -1;
        }
		else if(*Str >='0' && *Str <= '9')
		{
			// printf(".... %c  \r\n",*Str);
			//判断数字存在
			num_start = 1;
			//判断是否存在小数点
			if(num_point >= 1)
			{
				num_point++;
				//当前小数部分的数值
				float fpoint = *Str - '0';
				for(int i = 1;i<num_point;i++)
				{
					fpoint = fpoint/10.;
				}
				//加入小数部分
				*num = *num + fpoint;
			}
			else
			{
				//加入整数部分
				*num = *num*10+(*Str - '0');
			}
		}
		else if( *Str == '.') //判断为小数点
		{
			if(num_start==1)//发现存在小数点
			{
				num_point=1;
			}
		}
		else //判断为其他字符
		{
			if (num_start == 1)
			{
                // num[Fnum+1] = num[Fnum+1] * NorP;
				Fnum++;//统计个数加一
                NorP = 1;
			}
            break;
		}
		//指针移动
		*(Str++);
	}
    *num = (*num) * NorP;
    // printf(" ----------2222 end  %f \r\n", *num);
 
}

/* 整数除 10^coeff 后的浮点数*/
void Int2FloatByCoeff( float *funm, uint32_t num, uint8_t coeff)
{

    uint32_t i_v = num;
    float f_v = 0.;
    uint32_t n = num;
    for (size_t i = 0; i < coeff; i++)
    {
  
        f_v = (f_v + i_v%10)/10;
        i_v = i_v/10;
        printf(   " %d   %f ", i_v, f_v)    ;   
    }
    *funm =  (float)i_v + f_v;
    
}


void Float2Str(float fnum, char *str)
{
    uint32_t i_v = fnum;
    float f_v = 0.;
    i_v = i_v/1;
    f_v = fnum - (float) i_v;   
    int i = 0;

    while(1)
    {

    }

    // sprintf(str, "%f", fnum  );

}

/*需要转换的值*//*结果存储数组*//*小数位长度*/
/**
 * @brief 浮点转字符串
 * @param [in] value 
 * @param [in] cSendBuff 
 * @param [in] Decimals 
 * 
 * @details 
 */
void float2char(float value, char* cSendBuff, int Decimals) {
	int i = 1, k = 0;
	int integer = abs(value);//????
	int decimal = (fabs(value) - integer)*(int)pow(10, Decimals);//????
	int temp = integer;
	if (value < 0)cSendBuff[k++] = '-';//????0,????
	while (temp /= 10)
	{
		i*=10;
	}
	while (i) {
		cSendBuff[k++] = integer / i + '0';
		integer %= i;
		i /= 10;
	}
	if (Decimals == 0) {	//如果没有小数位，直接返回
		cSendBuff[k++] = '\0';
		return;
	}
	cSendBuff[k++] = '.';    //加上小数点
	temp = decimal;
	i = 1;
	while (temp /= 10)
	{
		i *= 10;
	}
	while (i) {
		cSendBuff[k++] = decimal / i + '0';
		decimal %= i;
		i /= 10;
	}
	cSendBuff[k++] = '\0';
	
}


void test_float(){
  log_i( "test f begin");
  //  float f[1] ={6.14};
   float f = 6.28 ;
   char aa[20] = "3.1415";
  //  float2char(f[0], aa , 4);
   float2char( f , aa , 4);
   log_i(" s  %s \r\n", aa);
  //  log_i(" f addr  %d \r\n",  f );
  //  log_i(" f HEX  %08X\r\n", f) ;

    uint32_t * pp = &f ;
   log_i(" ff HEX  %08X\r\n", *pp);

   log_i(" *** str to f test *** ");
   Str2Float( &f,   aa);
  if (f <4)
  {
    log_i(" str 2 float failure ");
  }else
  { 
	log_i("str 2 float ok");
	}

  //   double ff = 7.12;
  //  ff= strtod(aa, end);
  //  uint32_t addr = &f;
  // //  sprintf(aa, "%f", f);
  // log_i( "test f    %d   add :%d ---  %08X",sizeof(f) , addr, (char*)f);
  // log_i( "test f end  %s",aa);
  // f[0] = f[0]+8;
  // if (ff <4)
  // {
  //   log_i("f<4");
  // }else
  // { log_i(">6");}
  //  log_i(" after f HEX  %08X\r\n", (uint32_t *) f);

 }
/*  strtod用法
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

int main(void)
{
    // parsing with error handling
    const char *p = "111.11 -2.22 Nan nan(2) inF 0X1.BC70A3D70A3D7P+6  1.18973e+4932zzz";
    printf("Parsing '%s':\n", p);
    char *end;
    for (double f = strtod(p, &end); p != end; f = strtod(p, &end))
    {
        printf("'%.*s' -> ", (int)(end-p), p);
        p = end;
        if (errno == ERANGE){
            printf("range error, got ");
            errno = 0;
        }
        printf("%f\n", f);
    }

    // parsing without error handling
    printf("\"  -0.0000000123junk\"  -->  %g\n", strtod("  -0.0000000123junk", NULL));
    printf("\"junk\"                 -->  %g\n", strtod("junk", NULL));
}

*/