Форум программистов, компьютерный форум CyberForum.ru

Коррекция перевода float > char[] - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.82
insideone
Модератор
Автор FAQ
 Аватар для insideone
3619 / 897 / 47
Регистрация: 10.01.2010
Сообщений: 2,420
03.03.2010, 19:59     Коррекция перевода float > char[] #1
Вечер добрый! Задача такова - из float'а получить строку, но после запятой нужно оставить N знаков. Собственно я вывожу FPS на экран если конкретнее, а так в общем и для других целей сгодится.
Делаю так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define DOT_DIG_NUM 2
#define TEMP_SIZE 30
qString::qString(float newData){
    char newCharData[TEMP_SIZE] = {0};
/// start
    gcvt(newData, 1 + newData/10.0 + DOT_DIG_NUM, &newCharData[0]);
    int dot_pos = 0; while(newCharData[dot_pos] != '.') dot_pos++;
    if ( dot_pos >= TEMP_SIZE ) dot_pos = 0;
    char* AfterDot = &newCharData[dot_pos+1];
    for (int i = 0; i < DOT_DIG_NUM; i++)
    {
        if ( AfterDot[i] == 0 )
            AfterDot[i] = '0';
    }
    AfterDot[DOT_DIG_NUM] = 0;
/// end
    _new(&newCharData[0]);
}
При этом коде тут
C++
1
2
3
4
5
void qString::_new (const char* newData){
    if ( newData != NULL )
    {
        // Выделение памяти под полученную строку
        _size = strlen(newData) + 1; // тут
вылетает
Необработанное исключение в "0x00479982" в "WFAE.exe": 0xC0000005: Нарушение прав доступа при записи "0x00003034".
(адрес this - 0x00003030)
Впрочем ошибка не важна, хочется хороший алгоритм перевода написать, видно тот барахлит А без него все работает отлично
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nick Alte
Эксперт С++
1561 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
03.03.2010, 20:25     Коррекция перевода float > char[] #2
А чем не угодили sprintf и std::strstream?
insideone
Модератор
Автор FAQ
 Аватар для insideone
3619 / 897 / 47
Регистрация: 10.01.2010
Сообщений: 2,420
03.03.2010, 20:40  [ТС]     Коррекция перевода float > char[] #3
Нужно быстро и безопасно И вообще я не люблю пушкой по воробьям...
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
04.03.2010, 01:12     Коррекция перевода float > char[] #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от insideone Посмотреть сообщение
Нужно быстро и безопасно
Цитата Сообщение от Nick Alte Посмотреть сообщение
А чем не угодили sprintf и std::strstream?
И в правду - уж куда быстрей и безопаснее? Я бы тоже примерно так сделал:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
 
#define LEN 32
 
int main(void){
    int n;
    char template[LEN] = { 0 }, strval[LEN] = { 0 };
    double dval;
    
    printf("Double value: ");
    scanf("%lf", &dval);
    printf("Digits after point: ");
    scanf("%d", &n);
    
    snprintf(template, LEN - 1, "%%.%df", n);
    snprintf(strval, LEN - 1, template, dval);
    printf("As string: %s\n", strval);
    
    return 0;
}
Добавлено через 29 минут
вариант C++
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <sstream>
#include <string>
 
int main(){
    double dval;
    int n;
    std::string str;
    
    std::cout << "Double value: ";
    std::cin >> dval;
    std::cout << "Digits after point: ";
    std::cin >> n;
    
    std::stringstream ss;
    ss.setf(std::ios::fixed, std::ios::floatfield);
    ss.precision(n);
    ss << dval;
    ss >> str;
    
    std::cout << "As string: " << str << std::endl;
    
    return 0;
}
insideone
Модератор
Автор FAQ
 Аватар для insideone
3619 / 897 / 47
Регистрация: 10.01.2010
Сообщений: 2,420
04.03.2010, 01:25  [ТС]     Коррекция перевода float > char[] #5
2 easybudda: Если я не ошибаюсь достаточно 2 строчек По крайне мере это у меня работает верно
C++
1
2
char newCharData[TEMP_SIZE] = {0};
sprintf(&newCharData[0], "%." DOT_DIG_NUM "f", newData);
Быстра ли универсальная функция? Точно не быстрее узконаправленной (если качество кода одинаково). Про ненадежность просто читал где то и не раз. И то и другое важно - приложение игровое. Вернее даже... конечно безопасность вопрос сильный, и все же сейчас на первом плане скорость. К тому же мне просто интересно реализовать этот алгоритм без применения сторонних функций... Впринципе я то его и реализовал, но почему то ошибки вылетают

Не по теме:

А вообще чисто на подсознательном уровне эти printf функции кажутся консольными и мозолят глаза Интересно разработчики передовых трехмерных игр тоже их используют? :-D



Добавлено через 6 минут
Хм, вариант с std заинтересовал конечно, хотя вопрос... а накладные расходы на конструкцию
C++
1
std::stringstream ss;
и её убиение не убьют ли всю скорость? По крайне мере безопасности std я доверяю...
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2293 / 1663 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
04.03.2010, 03:11     Коррекция перевода float > char[] #6
Цитата Сообщение от easybudda Посмотреть сообщение
C++
1
2
3
4
5
// ...
  ss.setf(std::ios::fixed, std::ios::floatfield);
  ss.precision(n);
  ss << dval;
// ...
Этот фрагмент можно переписать чуть проще:
C++
1
2
3
4
#include <iomanip>
// ...
  ss << std::setprecision(n) << std::fixed << dval;
// ...
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
04.03.2010, 08:56     Коррекция перевода float > char[] #7
insideone, кстати, вот Вам ещё вариант. Не знаю, на сколько быстрый, крайне не устойчивый к плохим данным, но может, как идея, пригодится...
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>
#include <math.h>
 
#define LEN 32
 
char *strReverse(char *s){
    char *h, *t, c;
    for ( t = s; *t; ++t )
        ;
    for ( h = s, t -= 1; h < t; ++h, --t ){
        c = *h;
        *h = *t;
        *t = c;
    }
    return s;
}
 
char *doubleToStr(double d, int n, char *s){
    char *p = s;
    long num = (long)( d * pow(10, n) );
    while ( n-- ){
        *p++ = num % 10 + '0';
        num /= 10;
    }
    *p++ = '.';
    do {
        *p++ = num % 10 + '0';
        num /= 10;
    } while ( num );
    *p = 0;
    return strReverse(s);
}
 
int main(void){
    int n;
    double dval;
    char buf[LEN];
    
    printf("Double value: ");
    scanf("%lf", &dval);
    printf("Digits after point: ");
    scanf("%d", &n);
    
    printf("As string: %s\n", doubleToStr(dval, n, buf));
    
    return 0;
}
insideone
Модератор
Автор FAQ
 Аватар для insideone
3619 / 897 / 47
Регистрация: 10.01.2010
Сообщений: 2,420
04.03.2010, 16:03  [ТС]     Коррекция перевода float > char[] #8
Спасибо, становился на
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
long qString::_pow(unsigned char x , unsigned char n){
    long res = 1;
    while ( n-- ) res *= x;
return res;
}
 
char *qString::str_reverse(char *s){
    char *h, *t, c;
    for ( t = s; *t; ++t );
    for ( h = s, t -= 1; h < t; ++h, --t )
    {
        c = *h;
        *h = *t;
        *t = c;
    }
return s;
}
 
char* qString::_long2str(long Number, char* Dest, bool AddDot){
    do {
        *Dest++ = Number % 10 + '0';
        Number /= 10;
    }
    while ( Number );
    if ( AddDot ) *Dest++ = '.';
return Dest;
}
 
char* qString::_float2str(float Number, unsigned char DotDig, char* Dest){
    long int_part = Number;
    long rest_part = (Number - int_part) * _pow(10, DotDig);
    _long2str(int_part, _long2str(rest_part, Dest, true));
return str_reverse(Dest);
}
 
qString::qString(float newData){
    char newCharData[TEMP_SIZE] = {0};
    _float2str(newData, 2, &newCharData[0]);
    _new(&newCharData[0]);
}
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16821 / 5242 / 318
Регистрация: 30.03.2009
Сообщений: 14,118
Записей в блоге: 26
04.03.2010, 16:29     Коррекция перевода float > char[] #9
Цитата Сообщение от insideone Посмотреть сообщение
Быстра ли универсальная функция?
А зачем тебе в данном месте скорость? Ты же это значение так или иначе собираешься печатать на экран, всё равно это место (печать на экран) у тебя отожрёт основное время. Так стОит ли экономить на спичках?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.03.2010, 17:11     Коррекция перевода float > char[]
Еще ссылки по теме:

опять ошибка.на этот раз cannot convert `float (*)(float)' to `float' in argument passing C++
Преобразование char в float C++
C++ Float к char* без format и тп

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
insideone
Модератор
Автор FAQ
 Аватар для insideone
3619 / 897 / 47
Регистрация: 10.01.2010
Сообщений: 2,420
04.03.2010, 17:11  [ТС]     Коррекция перевода float > char[] #10
И вправду Я не думал в таком ракурсе... Впрочем на рендере не сэкономить особо, приходится заботится об остальном
Yandex
Объявления
04.03.2010, 17:11     Коррекция перевода float > char[]
Ответ Создать тему
Опции темы

Текущее время: 13:58. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru