тип данных

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
KIS
Начинающий
Начинающий
 
Сообщения: 5
Зарегистрирован: 20.04.2005 (Ср) 17:54

тип данных

Сообщение KIS » 20.04.2005 (Ср) 18:09

Всем привет!
Есть насущный вопрос. Через форму пользователь вводит в ячейку некое число с тремя десятичными знаками, тип переменной определен как Single. При этом в ячейке отображается число с 14 десятичными знаками. Например, вводится 4,488, а в ячейке 4,48800679843251. Почему и как этого избежать. Please :roll:

ism
Постоялец
Постоялец
 
Сообщения: 337
Зарегистрирован: 12.12.2001 (Ср) 12:59
Откуда: Russia, Saint-Petersburg

Сообщение ism » 20.04.2005 (Ср) 18:30

Много раз с этим сталкивался в делфях

Вроди-бы это из-за особенности хранения в памяти чисел с плавающей точкой
Число 4,488 храниться как 4488 * 10^(-3), попробуй тип Double

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 21.04.2005 (Чт) 5:32

Число 4.488 хранится совсем не так.
Ну ладно.

text1.text=format$(num,"0.000")
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

KIS
Начинающий
Начинающий
 
Сообщения: 5
Зарегистрирован: 20.04.2005 (Ср) 17:54

Сообщение KIS » 21.04.2005 (Чт) 9:56

Спасибо
С форматом получилось убрать лишние цифры, но почему вместо 4,488 теперь выводится 4488? :?:

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 21.04.2005 (Чт) 10:07

Замени во втором аргументе функции Format() точку на запятую.

ism
Постоялец
Постоялец
 
Сообщения: 337
Зарегистрирован: 12.12.2001 (Ср) 12:59
Откуда: Russia, Saint-Petersburg

Сообщение ism » 21.04.2005 (Чт) 11:13

GSerg
Представление чисел с плавающей точкой

text1.text=format$(num,"0,000")

А сравнивать лутше так
Код: Выделить всё

if abs(abs(a)-asb(b))<0.0001 then msgbox "Числа равны"

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 21.04.2005 (Чт) 11:54

"0,000"

Протестую.
В строке формата точка - десятичный разделитель, запятая - разделитель тысяч. См. MSDN.
У меня корректно работает именно с точкой.


ism
Настоящее представление чисел с плавающей точкой
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

vvs_adm
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1492
Зарегистрирован: 03.02.2005 (Чт) 3:45
Откуда: оттуда ;)

Сообщение vvs_adm » 21.04.2005 (Чт) 14:01

GSerg А разве не Пуск -> Настройка -> Панель управления -> язык и стандарты -> Разделитель целой и дробной части и т.д. :)

ism
Постоялец
Постоялец
 
Сообщения: 337
Зарегистрирован: 12.12.2001 (Ср) 12:59
Откуда: Russia, Saint-Petersburg

Сообщение ism » 21.04.2005 (Чт) 14:05

Могу предположить, зависит от региональных стандартов в системе.
Как и с Екселем одна версия на разных компьютерах работает поразному.
Способов борьбы незнаю.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 21.04.2005 (Чт) 14:20

Нет.
Строка формата не зависит от национальных настроек. наоборот, она придумана именно для того, чтобы поддерживать их. Если в строке формата стоит точка, то эта точка будет заменена на текущий национальный десятичный разделитель. Но в самой строке формата должна быть только точка.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 21.04.2005 (Чт) 14:21

ism писал(а):if abs(abs(a)-asb(b))<0.0001 then msgbox "Числа равны"


Внутренние abs'ы абсолютно лишние (попробуй сравнить 1 и -1).

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 21.04.2005 (Чт) 14:36

GSerg, я уже много раз сталкивался с глюками функций, форматирующих строки и числа, так что, вполне возможно, что у кого-то действительно нужно ставить ",". У меня, впрочем, все работает именно с точкой, хотя разделитель в региональных стандартах - запятая.

KIS
Начинающий
Начинающий
 
Сообщения: 5
Зарегистрирован: 20.04.2005 (Ср) 17:54

Сообщение KIS » 21.04.2005 (Чт) 16:03

По ходу дела выяснилась еще одна подробность. Если ставить "0.00", то все в порядке, число отображается как и должно (4,49), но стоит поставить "0.000" появляются тысячи (4488). И в чем собака порылась я понять не могу. Может кто-нибудь подскажет, а :roll:

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 21.04.2005 (Чт) 16:12

Побольше кода приведи.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

KIS
Начинающий
Начинающий
 
Сообщения: 5
Зарегистрирован: 20.04.2005 (Ср) 17:54

Сообщение KIS » 22.04.2005 (Пт) 9:32

Код достаточно длинный, но суть в следующем

Private Sub SF()
Dim x As Single
x = InputBox("Введите х")
Cells(1, 1).Value = Format$(x, "0.000")
End Sub

Вроде все просто, но что-то не так, а что, я никак не пойму :(

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 22.04.2005 (Пт) 9:57

Вот они и глюки пошли!!!
Тут, похоже, происходит несколько преобразований.
Сначала Format$ переводит число 4,4 в строку вида 4,400. Потом это значение вставляется в ячейку, НО эксель почему-то воспринимает "," не как разделитель разрядов, а как разделитель тысяч, в результате в ячейке получается 4400. У меня заработало так:

Код: Выделить всё
Cells(1,1).Value = Replace(Format$(x, "0.000"), ",", ".")


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

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 22.04.2005 (Пт) 10:45

Мда.
"Введите x"

Мда.

Во-первых, вводится строка, а не число.
Во-вторых, неизвестно, будет ли вводить пользователь в качестве десятичной точки точку, запятую, или ещё что. Поэтому нужно в приглашении для ввода написать, что именно ожидается в качестве разделителя. Потому что в общем случае сказать этого нельзя.
В-третьих, присваивать ячейке экселя нужно, не строку, а число, а потом наложить на ячейку nuberformat="0.000"
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 22.04.2005 (Пт) 11:15

GSerg писал(а):Во-вторых, неизвестно, будет ли вводить пользователь в качестве десятичной точки точку, запятую, или ещё что.


А я просто заменяю одно на другое (в зависимости от локали пользователя) - как результат всегда вводят правильно.
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 22.04.2005 (Пт) 11:28

А если пользователь введёт не точку и не запятую?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 22.04.2005 (Пт) 11:32

GSerg писал(а):А если пользователь введёт не точку и не запятую?


Сюда посмотри - вызывается при KeyPress:

Код: Выделить всё
Select Case FieldType
        ' Контроль ввода целочисленных полей
        Case adInteger, adSmallInt, adUnsignedTinyInt
            Select Case KeyAscii
                Case 48 To 57, Is < 32
                Case 45: If FieldType = adUnsignedTinyInt Then KeyAscii = 0
                Case Else: KeyAscii = 0
            End Select
        ' Контроль ввода полей с плавающей запятой
        Case adCurrency, adDouble, adSingle, adNumeric
            Select Case KeyAscii
                Case 44, 46: KeyAscii = g_iDecR
                Case 45, 48 To 57, Is < 32
                Case Else: KeyAscii = 0
            End Select
        ' Контроль ввода полей даты/времени
        Case adDate, adDBTimeStamp
            Select Case KeyAscii
                Case 44 To 47: KeyAscii = g_iDateR   ' .,/  ->  .
                Case 58, 59: KeyAscii = g_iTimeR   ' ;:   ->  :
                Case 48 To 57, Is <= 32
                Case Else: KeyAscii = 0
            End Select
    End Select


Пользователь может, конечно, скопировать билеберду через буфер обмена, но тут я решил не заморачиваться - просто ругнусь при валидации.
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

SeT
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 362
Зарегистрирован: 29.12.2004 (Ср) 13:11

Сообщение SeT » 22.04.2005 (Пт) 12:51

round(x,y) округляет число с заданной точностью
01000100
Причиняет боль 0010
Виртуальная любовь 00100
Индустрия снов 0010

KIS
Начинающий
Начинающий
 
Сообщения: 5
Зарегистрирован: 20.04.2005 (Ср) 17:54

Сообщение KIS » 22.04.2005 (Пт) 17:40

УРА!!!
REPLACE КАЖЕТСЯ СРАБОТАЛО. НАДЕЮСЬ НА ЭТОМ МОИ МУЧЕНИЯ ПО ДАННОЙ ТЕМЕ И В ДАННОМ СЛУЧАЕ ЗАКОНЧАТСЯ.
ВСЕМ СПАСИБО :P


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 132

    TopList