Лёгкая математика ...

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

Лёгкая математика ...

Сообщение _LEXA_ » 24.09.2006 (Вс) 22:26

Привет всем ... Помоги плиз разобраться в ошибке ...
Условие задачи простое : мы вводим положительное число, где целая цасть состоит из 4 цифр, а дробная - из 3 ... что-то вроде этого : 1234.456 ... Надо посчитать сумму цифр целой части, и произведение цифр дробной части ... С сумой всё норм. и с произведение тоже... но есть числа, для которых программа не работает (не правильно считает) .... Например для числа 1234.567 прога работает идеально .. а вот например для числа 6662.111 программа неправильно вычисляет произведение ... насколько я понял, не правильно "видирается" последняя цифра ... вместо единицы получается 0 ... сообтветственно и произведение тоже равно нулю ... в чём ошибка ?
вот код :
Код: Выделить всё
Number = Val(Text1.Text)
N1 = Number \ 1000 Mod 10
N2 = Number \ 100 Mod 10
N3 = Number \ 10 Mod 10
N4 = Fix(Number - N1 * 1000 - N2 * 100 - N3 * 10)
N5 = Number * 100 \ 10 Mod 10
N6 = Number * 1000 \ 10 Mod 10
N7 = Number * 10000 \ 10 Mod 10
S = N1 + N2 + N3 + N4
P = N5 * N6 * N7
Text2.Text = Str(S)
Text3.Text = Str(P)

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

Сообщение vvs_adm » 24.09.2006 (Вс) 22:37

Вообще вроде работает. Только почему n4 не равно Number mod 10? И не проще ли использовать Mid$?
Никогда не откладывай на завтра то, что можно ... отложить на послезавтра!

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Сообщение CodeName33 » 25.09.2006 (Пн) 8:29

vvs_adm, ага и у меня тоже всё работает правильно.
Программисты не глючат - глючат компиляторы...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 25.09.2006 (Пн) 8:50

_LEXA_

Код: Выделить всё
Mlt% = 1
For i = 1 to Len(Text1)
If i < InStr(1, Text1, ".") Then Sum% = Sum% + CInt(Mid$(Text1, i, 1))
If i > InStr(1, Text1, ".") Then Mlt% = Mlt% * CInt(Mid$(Text1, i, 1))
Next i
MsgBox "Сумма: " + CStr(Sum%) + vbNewLine + "Произведение: " + CStr(Mlt%)


Не правда ли короче, + работает с числами любой длины, и любого положения точки. (Т.е и для 12.34 и для 123678924.456654 )
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение GSerg » 25.09.2006 (Пн) 20:21

Хакер, если тебя восхищает объём кода, и тебе забить на то, что он медленный и весьма странный в контексте нормального программирования, то это слишком далеко от моего понимания.

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

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 25.09.2006 (Пн) 20:50

GSerg
Да... я действительно не вижу выгоду от каких-то (пусть даже 500 мс.) в конкретно данном случае.

Но код сделался за счёт этого (за счёт проигрыша в скорости), более универсальным - то что ж в этом плохого?

Теперь о правильности:
С каких пор принято считать, что операции со строками - это "неправильно" ?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение GSerg » 25.09.2006 (Пн) 20:59

Хакер писал(а):Но код сделался за счёт этого (за счёт проигрыша в скорости), более универсальным - то что ж в этом плохого?

То, что указанная универсальность достигается численными методами, без того самого проигрыша в скорости.

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

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 25.09.2006 (Пн) 21:55

GSerg
ок.
Покажи народу "численный метод" для числа
1111111111122222222222333333333344444444444455555555555666666666777777777778888888888899999999.123456789123456789

Свой же код, я лишь чуть-чуть отмодифю, поменяю TDC
Код: Выделить всё
Mlt& = 1
For i = 1 to Len(Text1)
If i < InStr(1, Text1, ".") Then Sum% = Sum% + CInt(Mid$(Text1, i, 1))
If i > InStr(1, Text1, ".") Then Mlt& = Mlt& * CInt(Mid$(Text1, i, 1))
Next i
MsgBox "Сумма: " + CStr(Sum%) + vbNewLine + "Произведение: " + CStr(Mlt&)


Теперь посмотрим, насколько код твоим методом, будет короче и понятнее метода, предложенного мной. :wink:

ЗЫ. Не подумай что я "объявляю войну" :) .
Просто интересно...
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение GSerg » 25.09.2006 (Пн) 23:17

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

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 26.09.2006 (Вт) 0:43

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


Ну так покажи мне численный метод, который будет действительно лучше чем предложенный мной и vss_adm
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 26.09.2006 (Вт) 7:33

Код: Выделить всё
Function GetDecBit(ByVal Value As Currency, ByVal BitOrder As Long) As Byte
Const Base As Currency = 10@
Dim res As Currency, K As Currency
K = Base ^ Abs(BitOrder)
Value = Abs(Value)
Select Case BitOrder
  Case 0
    res = 0@
  Case Is < 0
    res = Fix(Value * K) Mod Base
  Case Is > 0
    res = Value \ K Mod Base
End Select
End Function

Код: Выделить всё
Number = 123.456#
S = CLng(GetDecBit(Number, 3)) + GetDecBit(Number, 2) + GetDecBit(Number, 1)
P = CLng(GetDecBit(Number, -1)) * GetDecBit(Number, -2) * GetDecBit(Number, -3)
Lasciate ogni speranza, voi ch'entrate.

Matv
Новичок
Новичок
 
Сообщения: 26
Зарегистрирован: 13.11.2002 (Ср) 9:20
Откуда: Украина, Харьков

Сообщение Matv » 26.09.2006 (Вт) 11:31

Добавлю к обсуждению мнение непрофессионала.
Во первых, для числа 6662.111 исходный код действительно не работает корректно, т.к. N7 вычисляется как 0.
Применим пошаговое тестирование и вычислим N7.
Теперь разберёмся, что происходит при вычислении N7 = Number * 10000 \ 10 Mod 10
Отмаркируем Number * 10000 и посмотрим значение:
Number * 10000 = 6,662111Е+07
Аналогично смотрим:
Number * 10000 \ 10 = 6662110
Number * 10000 \ 10 Mod 10 = 0

Именно поэтому, из-за того, что промежуточное значение превышает интервал Integer применение целочисленного деления становится некорректным.

Я уже сталкивался с подобной проблемой и для анализа цифр в числе применяю только строки, как Хакер.

И не понимаю, почему у vvs_adm и CodeName33 код работал?
Может вопрос в объявлении переменных? Автор не указал этого, а я объявил их так:
Dim Number!, N1%, N2%, N3%, N4%, N5%, N6%, N7%, S%, P%

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 26.09.2006 (Вт) 11:36

Именно поэтому надо использовать число с фиксированной запятой.
Если хватает четырех знаков после запятой, то Currency.
Если не хватает -- то Long или Currency, а базу модифицировать вручную.
Lasciate ogni speranza, voi ch'entrate.

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Сообщение CodeName33 » 26.09.2006 (Вт) 11:37

Matv, да, похоже, дело именно в объявлении переменных. Я их вообще не объявлял, а просто скопировал код с экрана и оставил их вариантами...
Программисты не глючат - глючат компиляторы...

Matv
Новичок
Новичок
 
Сообщения: 26
Зарегистрирован: 13.11.2002 (Ср) 9:20
Откуда: Украина, Харьков

Сообщение Matv » 26.09.2006 (Вт) 11:51

Действительно, для Number As Currency работает корректно.
Никогда не применял это описание, буду теперь знать.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 26.09.2006 (Вт) 11:53

Только учитывай границы и целесообразность его применения.
Lasciate ogni speranza, voi ch'entrate.


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

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

Сейчас этот форум просматривают: Mail.ru [бот], SemrushBot и гости: 139

    TopList