Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > ошибка округления ADO


Автор: stmamont 29.4.2007, 20:00
база данных хранит число типа real
например 123.1

если я делаю запрос (через адо конечно же),

а потом
double t = mQuery->FieldByName("limit1")->AsFloat;
то в t лежит что то типа 123.99992234532
Как мне сделать что бы отображалось нормально?

В DataGrid таже самая проблема.

Очень нужно решение этой мини проблемки)

Автор: Klin 29.4.2007, 20:53
ИМХО компьютер не хранит число 4, он хранит, что-то типа 3,99987

Автор: stmamont 29.4.2007, 21:00
когда делаю запрос через phpPgSql - все так и есть как записал т.е. 123.1
а когда отображаю инфу через ADO , то получается такой бред.
как мне отображать нормально, т.е. 123.1?

Автор: codelord 29.4.2007, 21:40
вот накидал функцию,
 
Код

#include <iostream>
#include <math.h>
using namespace std;
double round( double val, int dem  ) {   // 4.99 49.9
 val *= pow( 10, dem );
 val = floor( val + 0.5 );
 val /= pow( 10, dem );
 return val;
}
 int main( int argc, char **argv )
{
 double m = 4.9856;
 cout << round( m, 0 ) << endl;    //4.9856 5.0
 cout << round( m, 2 ) << endl;    //4.9856 4.99
 cout << round( m, 3 ) << endl;    //4.9856 4.986

 m = 123.99992234532;
 cout << round( m, 2 ) << endl; // 123.99992234532 124.00;
 m = 123.099992234532;
 cout << round( m, 2 ) << endl; // 123.099992234532 123.1;
 return 0; 
}
 может поможет

Автор: Vyacheslav 29.4.2007, 22:35
Цитата(stmamont @  29.4.2007,  20:00 Найти цитируемый пост)
В DataGrid таже самая проблема.

Это ошибка не гриде, а в голове, когда полагают, что предствление числа в бинарном виде и форма вывода числа - это одно и то же.
Цитата(codelord @  29.4.2007,  21:40 Найти цитируемый пост)
вот накидал функцию,

И для чего?
Конкретная задача должна иметь конкретное и простое решение. 
Посказка.
1. Для TQuery можно создать колекцию требуемых TField  в дизайне. Кстати , профессионалы именно так обычно и делают. А для Field можно задать требуемый форма вывода: например фиксированный  с двумя цифрами после  запятой. 

Автор: stmamont 29.4.2007, 23:33
codelord, для округления числа есть функция RoundTo из Math.hpp
Vyacheslav, да понимаю я что проблемы не в хранении числа, а в выводе,
у меня и TQuery создается во время выполнения программы...
как задать постоянный формат для Fields сразу после кода, где создается TQuery?
?
я попробовал сделать так:
Код

    if(Sender)
    {
        TField *field = new TFloatField(monthsPlanQuery);
        dynamic_cast<TFloatField *>(field)->Precision = -2;
        field->Name = "planed";
        monthsPlanQuery->Fields->Add(field);

        field = new TFloatField(monthsPlanQuery);
        dynamic_cast<TFloatField *>(field)->Precision = -2;
        field->Name = "used";
        monthsPlanQuery->Fields->Add(field);

        field = new TIntegerField(monthsPlanQuery);
        field->Name = "id";
        monthsPlanQuery->Fields->Add(field);

        field = new TIntegerField(monthsPlanQuery);
        field->Name = "year";
        monthsPlanQuery->Fields->Add(field);

        field = new TIntegerField(monthsPlanQuery);
        field->Name = "month";
        monthsPlanQuery->Fields->Add(field);
    }


а потом делать SQL запрос, но у меня не получилось,
Код

    monthsPlanQuery->SQL->Text = "select id , " + AnsiString(YearStart->Position) + " + number / 12 as year , number %12 + 1 as month , planed , used from avtodormonths where objectsubdivisionid = " + AnsiString(subDivisionQuery->FieldByName("osdid")->AsInteger) + " order by number";
    monthsPlanQuery->Active = true;
    monthsPlanQuery->FieldByName("id")->Visible = false;


на последней строчке ругается на то что Field "id" не найдено

Автор: FFFFFFF7 30.4.2007, 20:11
Цитата(stmamont @  29.4.2007,  23:33 Найти цитируемый пост)
на последней строчке ругается на то что Field "id" не найдено

его нет в объекте, хоть и есть в запрсе.
Цитата(Vyacheslav @  29.4.2007,  22:35 Найти цитируемый пост)
 колекцию требуемых TField  в дизайне.

прочитайте внимательнее.
Цитата(Klin @  29.4.2007,  20:53 Найти цитируемый пост)
ИМХО компьютер не хранит число 4, он хранит, что-то типа 3,99987

лол
//по сабжу: На крайняк есть RoundTo().

Автор: stmamont 1.5.2007, 07:43
FFFFFFF7, 
а это что?
Код

        field = new TIntegerField(monthsPlanQuery);
        field->Name = "id";
        monthsPlanQuery->Fields->Add(field);

я добавил id
Цитата(FFFFFFF7 @  30.4.2007,  20:11 Найти цитируемый пост)
На крайняк есть RoundTo(). 

ага. по всей программе, во всем полях и datagrid'ах. прикольно наверное.

больше интересует решенеи с предустановкой TFields после создания кода.
Помогите! почему мой код не работает???
завтра уже нужно показать, а тут такой косяк!!!

Автор: Vyacheslav 1.5.2007, 18:23
Цитата(stmamont @  29.4.2007,  23:33 Найти цитируемый пост)
у меня и TQuery создается во время выполнения программы...

Когда я встречаю подобные фразы, у меня возникает вопрос:"А нафига?"
Кончено бывают случаи, когда есть смысл это делать в рантайме, но в большинстве случаев - это просто понты. Вы можете привести реальные причины, побудившие Ваc принять такое решение?

Добавлено через 6 минут и 32 секунды
Цитата(stmamont @  1.5.2007,  07:43 Найти цитируемый пост)
Помогите! почему мой код не работает???
завтра уже нужно показать, а тут такой косяк!!! 

Ну какие Вы все таки беспомощные. Нежели трудно хелп поглядеть. Тем более, что подсказка уже была
Цитата(Vyacheslav @  29.4.2007,  22:35 Найти цитируемый пост)
А для Field можно задать требуемый форма вывода: например фиксированный  с двумя цифрами после  запятой.  

Открываем хелп для TFloatField и находим проперти DisplayFormat

Автор: stmamont 2.5.2007, 08:39
В общем, у меня "почти" получилось сделать то, что я хотел.
Делается это следующим образом в моем случае
Код

        TField *field = new TAutoIncField(0);
        field->FieldName = "id";
        field->DataSet = subDivisionQuery;

        field = new TStringField(0);
        field->FieldName = "name";
        field->DataSet = subDivisionQuery;

        field = new TIntegerField(0);
        field->FieldName = "osdid";
        field->DataSet = subDivisionQuery;

        field = new TFloatField(0);
        dynamic_cast<TFloatField *>(field)->DisplayFormat = "#.##";
        field->FieldName = "limits";
        field->DataSet = subDivisionQuery;


и после этого, делаю sql запрос и продолжаю работать.
Отображение в DataGrid'е, DBEdit'е теперь именно такое как нужно.
Но когда я пробую
Код

Edit1->Text = subDivisionQuery->FieldByName("limits")->AsString;

все по старому

Вопрос: Как сделать чтобы DisplayFormat распространялся не только на DataControls?

Автор: Vyacheslav 2.5.2007, 11:54
Эхх  smile 
Код

Edit1->Text = subDivisionQuery->FieldByName("limits")->DisplayText;


Добавлено через 7 минут и 34 секунды
Кстати, для гибкости  работы с полями существуют  еще события 
Код

__property TFieldGetTextEvent OnGetText = {read=FOnGetText, write=FOnGetText};
__property TFieldSetTextEvent OnSetText = {read=FOnSetText, write=FOnSetText};

С помощью которых, можно вообще подменять то, что будет выводится в контролах.



Автор: bas 2.5.2007, 12:14
Код

double Round(double Argument, int Precision)
{ double div = 1.0;
  if(Precision < 0) while(Precision++) div /= 10.0;
  else while(Precision--) div *= 10.0;
  return floor(Argument * div + 0.5) / div;
}


Добавлено через 2 минуты и 26 секунд
А почему не воспользоваться CAST в запросе?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)