Автор | Сообщение |
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 26.04.06 01:41. Заголовок: Количество десятичных знаков в Clipper
Кто знает, как определить количество назначенных числу десятичных знаков, например, 10.0 или 10.000? Или чуть проще: как отличить изначальное целое число от дробного результата каких-либо вычислений? INT() помогает только если дробная часть ненулевая...
|
|
|
Ответов - 32
, стр:
1
2
All
[только новые]
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 26.04.06 08:19. Заголовок: Re:
x:=10.00000001 y:=int(x) ? x==y
|
|
|
|
| постоянный участник
|
Не зарегистрирован
Зарегистрирован: 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.
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 27.04.06 00:38. Заголовок: Re:
Именно "как отличить изначальное целое число от дробного результата каких-либо вычислений" я делаю так: проверяю CEILING() равно FLOOR()? Это из CLIPPER TOOLS II Одна функция округляет до ближайшего большего целого, другая - до ближайшего меньшего целого. Если они равны, то значит и аргумент целый.
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 27.04.06 01:28. Заголовок: Re: MikeP
CEILING() и FLOOR() я, конечно, попробую, но подозреваю, что разницу между 10 и 10.000 они мне не покажут... В том-то и проблема, что в дробной части могут быть сплошные нули, а определить, что это число не целое, а "как бы дробное", необходимо.
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 27.04.06 01:34. Заголовок: Re:
Dima пишет: цитата: | x:=10.00000001 y:=int(x) ? x==y |
| Дима, ты, наверное, не понял сути проблемы. А она в том, что в функцию, которая может быть вызвана из десятка мест в программе, приходит параметр, и если он целое число, то его нужно перед дальнейшими действиями в этой функции разделить на 1000, а если дробное, то оставить как есть. Проблема в том, что дробное число может быть и 10.000, т.е. в десятичных знаках могут быть одни нули, НО: число от этого не перестаёт быть дробным, и на 1000 его делить, соответственно, категорически не нужно...
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 27.04.06 01:39. Заголовок: Re:
Григорьев Владимир пишет: цитата: | Но, я уже не помню, где-то внутри Clipper я встречал функцию, которая четко заносит в Decimals число десятичных знаков для данного внутреннего представления Double. |
| Осталось только понять, как называется эта функция, а также как из Clipper получить доступ к значению Decimals
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 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() даст ответ на вопрос, како же в итоге внутренний рузультат получился?
|
|
|
|
| постоянный участник
|
Не зарегистрирован
Зарегистрирован: 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
|
|
|
|
| постоянный участник
|
Не зарегистрирован
Зарегистрирован: 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
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 27.04.06 11:57. Заголовок: Re:
if At('.', Str(NUM))> 0 //REAL else //INTEGER endif
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 28.04.06 06:14. Заголовок: Re:
MikeP пишет: цитата: | Возможно str() даст ответ на вопрос, како же в итоге внутренний рузультат получился? |
| Не знаю, не знаю... У меня STR(целое число) выдаёт результат с двумя нулями после точки...
|
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 28.04.06 06:17. Заголовок: Re:
Григорьев Владимир пишет: цитата: | Написать самому функцию типа IsLong( nNumParm ). |
| К сожалению, ни в асссемблере, ни в C программить не умею
|
|
|
|
| постоянный участник
|
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 28.04.06 10:24. Заголовок: Re:
Лукашевский цитата: | К сожалению, ни в асссемблере, ни в C программить не умею |
| Сообщите адрес, и я вам завтра вышлю готовый объектный файл, готовый к употреблению.
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 02.05.06 07:23. Заголовок: Re:
Григорьев Владимир пишет: kniga@online.ru
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 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 ); }
|
|
|
|
| постоянный участник
|
Не зарегистрирован
Зарегистрирован: 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-ом, и может содержать что угодно. Поэтому не следует полагаться на то, что вызвав эту вашу функцию, программист получит что-нибудь значещее.
|
|
|
|
| постоянный участник
|
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 02.05.06 12:18. Заголовок: Re:
Лукашевский, получите посылочку.
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 02.05.06 14:01. Заголовок: Re:
поле wLen и wDec обычно содержит "грязь", и программист только получает возможность увидеть, что там находится.
|
|
|
|
| постоянный участник
|
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 02.05.06 14:18. Заголовок: Re:
Для данных типа Long поле wLen, если заполнено, то обычно содержит число 10.
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 02.05.06 16:06. Заголовок: Re:
Для данных типа REAL поле wDec, если заполнено, то обычно содержит число Set(_SET_DECIMALS), а поле wLen, если заполнено, то обычно содержит число 10 + Set(_SET_DECIMALS) + 1.
|
|
|
Ответов - 32
, стр:
1
2
All
[только новые]
|
|