On-line: гостей 0. Всего: 0 [подробнее..]
АвторСообщение





Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 26.04.06 01:41. Заголовок: Количество десятичных знаков в Clipper


Кто знает, как определить количество назначенных числу десятичных знаков, например, 10.0 или 10.000? Или чуть проще: как отличить изначальное целое число от дробного результата каких-либо вычислений? INT() помогает только если дробная часть ненулевая...

Спасибо: 0 
Профиль
Ответов - 32 , стр: 1 2 All [только новые]


администратор




Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 26.04.06 08:19. Заголовок: Re:


x:=10.00000001
y:=int(x)
? x==y


Спасибо: 0 
Профиль
постоянный участник


Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 26.04.06 11:25. Заголовок: Re:


Надо узнать, какой тип данных возвращает Clipper. Для чисел у Clipper имеется два внутренних формата представления: Long (длинное целое) и Double (десятичное двойной точности)ю Если результат возвращается в виде Long, то очевидно никаких десятичных знаков нет. Если же в виде Double, то тут трудно определить. Double у Clipper хранится в формате Microsoft.
Вот структура внутреннего представления Double (ассемблер TASM)

STRUC DoubleHandleStr
Type dw ?
Length dw ?
Decimals dw ?
DoubleValue dq ? ; or dw 4 DUP( ? )
ENDS DoubleHandleStr

Я не знаю, на сколько будет корректно проверять поле Decimals на равенство нулю. Но, я уже не помню, где-то внутри Clipper я встречал функцию, которая четко заносит в Decimals число десятичных знаков для данного внутреннего представления Double.

Спасибо: 0 
Профиль



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 27.04.06 00:38. Заголовок: Re:


Именно "как отличить изначальное целое число от дробного результата каких-либо вычислений" я делаю так:
проверяю CEILING() равно FLOOR()? Это из CLIPPER TOOLS II
Одна функция округляет до ближайшего большего целого, другая - до ближайшего меньшего целого. Если они равны, то значит и аргумент целый.

Спасибо: 0 





Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 27.04.06 01:28. Заголовок: Re: MikeP


CEILING() и FLOOR() я, конечно, попробую, но подозреваю, что разницу между 10 и 10.000 они мне не покажут... В том-то и проблема, что в дробной части могут быть сплошные нули, а определить, что это число не целое, а "как бы дробное", необходимо.

Спасибо: 0 
Профиль





Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 27.04.06 01:34. Заголовок: Re:


Dima пишет:

 цитата:
x:=10.00000001
y:=int(x)
? x==y


Дима, ты, наверное, не понял сути проблемы. А она в том, что в функцию, которая может быть вызвана из десятка мест в программе, приходит параметр, и если он целое число, то его нужно перед дальнейшими действиями в этой функции разделить на 1000, а если дробное, то оставить как есть. Проблема в том, что дробное число может быть и 10.000, т.е. в десятичных знаках могут быть одни нули, НО: число от этого не перестаёт быть дробным, и на 1000 его делить, соответственно, категорически не нужно...

Спасибо: 0 
Профиль





Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 27.04.06 01:39. Заголовок: Re:


Григорьев Владимир пишет:

 цитата:
Но, я уже не помню, где-то внутри Clipper я встречал функцию, которая четко заносит в Decimals число десятичных знаков для данного внутреннего представления Double.


Осталось только понять, как называется эта функция, а также как из Clipper получить доступ к значению Decimals

Спасибо: 0 
Профиль



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 27.04.06 07:38. Заголовок: Re:


Еще один эксперимент:
? str(1/2)
? str(2/1)
? str(2.3/2.3)
? str(2/2)

Результаты:
0.50
2
1.00
1

Возможно str() даст ответ на вопрос, како же в итоге внутренний рузультат получился?

Спасибо: 0 
постоянный участник


Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 27.04.06 11:41. Заголовок: Re:


Лукашевский
 цитата:
Осталось только понять, как называется эта функция, а также как из Clipper получить доступ к значению Decimals


Написать самому функцию типа IsLong( nNumParm ).
Что-то вродк такого ( Borland TASM 4.01; не проверялась )

TITLE THE AUXILIARY CLIPPER 5.XX FUNCTION ISLONG

IDEAL

MODEL LARGE ISLONG_TEXT, CPP

%NOINC
INCLUDE "CTYPE.INC" ; в этот файл внести определение AnyHandleStr

GLOBAL __retl: PROC
GLOBAL __param: PROC

GLOBAL IsLong: PROC

False = 0000h
True = 0001h
Long = 0002h
AnyType = 0FFFFh

CODESEG ISLONG_TEXT

; Function format
: IsLong( <nNumParm> ) --> lIsLong

PROC IsLong
mov ax,AnyType
push ax
mov ax,1
push ax
call __param
add sp,4
or ax,ax
jz @@10
mov bx,ax
test [(AnyHandleStr bx).Type],Long
jz @@10
mov ax,True
@@10:
call __retl,ax
ret
ENDP IsLong

END




Спасибо: 0 
Профиль
постоянный участник


Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 27.04.06 11:48. Заголовок: Re:


Извините, в моем коде ошибочка закралась!

PROC IsLong
mov ax,AnyType
push ax
mov ax,1
push ax
call __param
add sp,4
or ax,ax
jz @@10
mov bx,ax
test [(AnyHandleStr bx).Type],Long
jz @@10
mov ax,True
jmp short @@20
@@10:
mov ax,False
@@20:
call __retl,ax
ret
ENDP IsLong



Спасибо: 0 
Профиль



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 27.04.06 11:57. Заголовок: Re:


if At('.', Str(NUM))> 0
//REAL
else
//INTEGER
endif

Спасибо: 0 
Профиль





Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 28.04.06 06:14. Заголовок: Re:


MikeP пишет:

 цитата:
Возможно str() даст ответ на вопрос, како же в итоге внутренний рузультат получился?


Не знаю, не знаю... У меня STR(целое число) выдаёт результат с двумя нулями после точки...

Спасибо: 0 
Профиль





Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 28.04.06 06:17. Заголовок: Re:


Григорьев Владимир пишет:

 цитата:
Написать самому функцию типа IsLong( nNumParm ).


К сожалению, ни в асссемблере, ни в C программить не умею

Спасибо: 0 
Профиль
постоянный участник


Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 28.04.06 10:24. Заголовок: Re:


Лукашевский

 цитата:
К сожалению, ни в асссемблере, ни в C программить не умею


Сообщите адрес, и я вам завтра вышлю готовый объектный файл, готовый к употреблению.


Спасибо: 0 
Профиль





Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 02.05.06 07:23. Заголовок: Re:


Григорьев Владимир пишет:

 цитата:
Сообщите адрес


kniga@online.ru

Спасибо: 0 
Профиль



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 02.05.06 09:55. Заголовок: Re:


/*
Translate (Borland C++ 5.2) :

BCC -2 -c -ml -O2 -w -X -Z -IC:\BC5\INCLUDE test.c

FUNCTIONS:
=========

IsNumeric( <nExp> ) --> lNumeric (.t. if number type is NUMERIC)
IsFloat( <nExp> ) --> lFloat (.t. if number type is FLOAT)
NumLen( <nExp> ) --> nLen (number length from nExp variable)
NumDec( <nExp> ) --> nDec (number decimals from nExp variable)

where nExp - any valid numeric parameter or expression

*/


#include <Windows.h> //only declare types


#define NUMERIC 0x0002
#define NUM_FLOAT 0x0008
#define ANYNUMBER 0x000A


typedef struct {
WORD wType;
WORD wLen;
WORD wDec;
WORD wNumber[4];
} CLIPVAR, near * PCLIPVAR;


extern PCLIPVAR _param( WORD wParam, WORD wType );
extern void _retni( WORD wNumber );
extern void _retl( BOOL );



void pascal ISNUMERIC( void )
{
_retl( _param( 1, NUMERIC ) != 0 );
}



void pascal ISFLOAT( void )
{
_retl( _param( 1, NUM_FLOAT ) != 0 );
}



void pascal NUMLEN( void )
{
PCLIPVAR pVar = _param( 1, ANYNUMBER );

_retni( pVar ? pVar->wLen : 0 );
}



void pascal NUMDEC( void )
{
PCLIPVAR pVar = _param( 1, ANYNUMBER );

_retni( pVar ? pVar->wDec : 0 );
}

Спасибо: 0 
Профиль
постоянный участник


Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 02.05.06 11:57. Заголовок: Re:


saulius, на самом деле вы указали не совсем корректные функции. Я имею в виду, например, последнюю вашу функцию.

 цитата:
void pascal NUMDEC( void )
{
PCLIPVAR pVar = _param( 1, ANYNUMBER );

_retni( pVar ? pVar->wDec : 0 );
}



Дело в том, что часто поле wDec содержит "грязь", так как это поле особенно для типа Long просто не заполняется Clipper-ом, и может содержать что угодно. Поэтому не следует полагаться на то, что вызвав эту вашу функцию, программист получит что-нибудь значещее.

Спасибо: 0 
Профиль
постоянный участник


Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 02.05.06 12:18. Заголовок: Re:


Лукашевский, получите посылочку.


Спасибо: 0 
Профиль



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 02.05.06 14:01. Заголовок: Re:


поле wLen и wDec обычно содержит "грязь", и программист только получает возможность увидеть,
что там находится.


Спасибо: 0 
Профиль
постоянный участник


Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 02.05.06 14:18. Заголовок: Re:


Для данных типа Long поле wLen, если заполнено, то обычно содержит число 10.

Спасибо: 0 
Профиль



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 02.05.06 16:06. Заголовок: Re:


Для данных типа REAL поле wDec, если заполнено, то обычно содержит число
Set(_SET_DECIMALS),
а поле wLen, если заполнено, то обычно содержит число
10 + Set(_SET_DECIMALS) + 1.

Спасибо: 0 
Профиль
Ответов - 32 , стр: 1 2 All [только новые]
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 33
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет