static double pfc_string_to_float_internal(const char * src)
{
	bool neg = false;
	t_int64 val = 0;
	int div = 0;
	bool got_dot = false;

	while(*src==' ') src++;

	if (*src=='-') {neg = true;src++;}
	else if (*src=='+') src++;
	
	while(*src)
	{
		if (*src>='0' && *src<='9')
		{
			int d = *src - '0';
			val = val * 10 + d;
			if (got_dot) div--;
			src++;
		}
		else if (*src=='.' || *src==',')
		{
			if (got_dot) break;
			got_dot = true;
			src++;
		}
		else if (*src=='E' || *src=='e')
		{
			src++;
			div += atoi(src);
			break;
		}
		else break;
	}
	if (neg) val = -val;
    return (double) val * exp_int(10, div);
}
Example #2
0
// Основная функция. На вход: EPS --- порядок погрешности
// filename --- файл для вывода, local --- значения локальной погрешности в точках
int runge(double *global_error, double EPS, const char*filename, double local[CHECK_POSITIONS * VAL_NUM ])
{
    double x,y,u,v; // x y a b
    double h=0;

    double k[K_NUM][VAL_NUM]; // числа рунге
    int errflag = 0;
    int check_time = CHECK_POSITIONS; // количество оставшихся точек на временной шкале для проверки лок погрешности
    int flag = 0;
    double h_next = 0; // механическая переменная для хранения следующего шага

    *global_error = 0;

    FILE *file = fopen(filename, "w");

    if (file == NULL) errflag = -1;
    else{
        fprintf(file, "t,  x,  y\n");

        //вводим начальные условия
        x = x0;    y = y0;    u = u0;   v = v0;   h = EPS/h0;
        new_k(h,k,x,y,u,v); // начальные числа Рунге
        h = new_h(EPS,h,k,x,y,u,v); // обновляем шаг
        new_k(h,k,x,y,u,v); // ежели он изменился -- обновим числа Рунге

        for (double t = 0;t<=WORK_TIME+h;t+=h){
            // если мы в нужной точке T, 3T/4, T/2, T/4, то flag == 1 

            if (flag == 0)
                if (check_time > 0) // если меньше, то точек не осталось, увы
                        if ((nearest(t) - t <= h)&&(nearest(t) - t >= 0)){
                            // если мы сюда попали, то расстояние до нужной точки меньше h
                            // объявим следующий шаг этим расстоянием
                            h_next = nearest(t) - t;
                        }


            //подсчет глобальной погрешности
            (*global_error) = Variation(h,k,x,y,u,v) + (*global_error) * exp_int(h,x,y);

        // обновляем координаты
            x = new_parametr(h,x,k,x,y,u,v,0);
            y = new_parametr(h,y,k,x,y,u,v,1);
            u = new_parametr(h,u,k,x,y,u,v,2);
            v = new_parametr(h,v,k,x,y,u,v,3);
            fprintf(file, "%e,  %e,  %e\n", t,x,y);
            // если мы в нужной точке T, 3T/4, T/2, T/4, то flag == 1 
            if (flag == 1) {
                local[CHECK_POSITIONS*(CHECK_POSITIONS - check_time)] = x;
                local[CHECK_POSITIONS*(CHECK_POSITIONS - check_time) + 1] = y;
                local[CHECK_POSITIONS*(CHECK_POSITIONS - check_time) + 2] = u;
                local[CHECK_POSITIONS*(CHECK_POSITIONS - check_time) + 3] = v;
                h = h_next; // возвращаем исходное значение шага 
                h_next = 0; 
                flag = 0;
                check_time--; // мы же уже дошли до этой точке, осталось на одну меньше
            }

            h = new_h(EPS,h,k,x,y,u,v); //обновляем шаг

            if (h_next != 0){
                double p;
                p = h;
                h = h_next;
                h_next = p;//сохраняем предыдуший шаг на случай, если новый слишком маленький
                flag = 1; // для того, чтобы мы видели вывод
            }
            
            new_k(h,k,x,y,u,v); //обновляем числа Рунге
           
            if (h<H_DEFAULT) {errflag = -2; break;} // на случай особых точек
        }
    }
    printf("final step = %e;\n", h);
    fclose(file);
    return errflag;
}