Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.88/32: Рейтинг темы: голосов - 32, средняя оценка - 4.88
Fidyum4yk
0 / 0 / 0
Регистрация: 09.11.2012
Сообщений: 40
1

Функция pow(); из math.h с переменными считает не правильно?

13.11.2012, 12:01. Просмотров 6089. Ответов 17
Метки нет (Все метки)

Код
//Функция преобразования
void IND_Conv(unsykned char value)
{
unsykned int tmp,st;
unsykned char i;
for (i=SEG;i>=1;i--)
{
if (i==1){tmp=value;} else

//смотреть здесь!!!!
{tmp=i-1;
st=pow(10,tmp);
//////////////////////////////////////
tmp = value /st;
value %= st;}
data[i-1] =  number[tmp];
}
}
Собственно при прогонке в отладчике смотрю пошагово tmp=i-1 результат выдает 3 - верно, следующий шаг функция pow() выдает результат 999 вместо 1000. Все переменные целочисленные (int,char). В чем может быть дело? Я что-то не так делаю?

0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.11.2012, 12:01
Ответы с готовыми решениями:

Math.pow()
Всем привет, пишу калькулятор, необходимо чтобы из инпутов считывалось значение, записывалось в...

Метод Math.pow()
Вопрос а почему метод Math.pow() при единице в степени 2 возвращает число 2? Если 1 в степени 2...

Math.pow() - возвращает 1
public static final double r0 = 1.23 * Math.pow(10, -15); /** * повертаэ значення...

Функция не правильно считает матрицу
Заданная матрица порядка н. Найти максимальное значение элементов, которые находятся в...

17
THI BIOST
0 / 0 / 0
Регистрация: 23.01.2010
Сообщений: 1,142
13.11.2012, 12:27 2
pow функция плавучая, как в аргументах, так и в результате, считает через логарифмы, так-что ошибки округления (по умолчанию int->ftoot отбрасывает дробную часть). Не надо вносить сущности сверх необходимых - считаете в целых - и считайте в них дальше.
0
Fidyum4yk
0 / 0 / 0
Регистрация: 09.11.2012
Сообщений: 40
13.11.2012, 16:12 3
Т.е. не использовать функцию Pow и вместо нее запустить цикл с перемножением???
0
THI BIOST
0 / 0 / 0
Регистрация: 23.01.2010
Сообщений: 1,142
13.11.2012, 16:27 4
Да. Основное правило - не использовать операции с плавающей точкой. В 99% использования плавающей точки неоправданно.

Кстати, заменив pow на цикл увидите, что код сильно похудеет.

А в Вашей программе, подозреваю, и цикл не нужен, если переписать грамотно.
0
omx
13.11.2012, 16:34 5
Цитата Сообщение от Fidyum4yk
Т.е. не использовать функцию Pow и вместо нее запустить цикл с перемножением???
К тому же это будет быстрее по времени.
Stiit.mi
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
13.11.2012, 18:04 6
Причем не просто цикл, а с учетом того, что можно аккумулятор возвести в квадрат, а степень поделить на два.
т.е алгоритм такой - найти x^y
(0) Помещаем в аккумулятор основание (a=x)
(1) Если y - четное число, тогда a=a*a; y=y/2;
Иначе a=a*x; y=y-1;
(2) Повторять (1), пока y>1;
0
Fidyum4yk
0 / 0 / 0
Регистрация: 09.11.2012
Сообщений: 40
13.11.2012, 18:18 7
Цитата Сообщение от THI BIOST
А в Вашей программе, подозреваю, и цикл не нужен, если переписать грамотно.
Без цикла никак. Т.к. заранее степень числа неизвестна и зависит от кол-ва разрядов числа, передаваемого в функцию.
Функция разбивает его на разряды и записывает BCD код в массив и его можно выводить на 7 сегментный индикатор. Что-то вроде универсального драйвера для 7-сегментника с n разрядами.

Например 4356
// 0 1 2 3 4 5 6 7 8 9
unsykned char number[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
в итоге получим массив,где
data[0]=0x66 //4
data[1]=0x4f //3
data[2]=0x6d //5
data[3]=0x7d //6

P.S. Не хочу сказать что этот код грамотный. Сейчас мне это интересно реализовать таким способом в учебных целях. Потом хочу попробовать реализовать это же методом вычитания.

За советы с циклом Всем спасибо. Единственное чего не могу понять: tmp=3, pow(10,tmp)=999; а если сделать так pow(10,3) в итоге все норм = 1000.
0
//Mt
0 / 0 / 0
Регистрация: 20.06.2010
Сообщений: 456
13.11.2012, 18:27 8
Цитата Сообщение от Fidyum4yk
Единственное чего не могу понять: tmp=3, pow(10,tmp)=999; а если сделать так pow(10,3) в итоге все норм = 1000.
Думаю, что в случае pow(10,3) функция pow() вообще не вызывается, оптимизатор должен подставить константу.... можно посмотреть это в листинге, скажем.
0
Stiit.mi
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
13.11.2012, 18:53 9
Вот тут-то и выясняется, что pow и не нужен, а нужно преобразовать число в строку )
0
Bytt
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
15.11.2012, 10:21 10
Цитата Сообщение от //Mt
Цитата Сообщение от Fidyum4yk
Единственное чего не могу понять: tmp=3, pow(10,tmp)=999; а если сделать так pow(10,3) в итоге все норм = 1000.
Думаю, что в случае pow(10,3) функция pow() вообще не вызывается, оптимизатор должен подставить константу.... можно посмотреть это в листинге, скажем.Зря так думаете. Компилятор просто не "знает" что такое функция pow(). Он также ничего не "знает" и о множестве остальных библиотечных функций. Так что в подобных случаях такие функции нужно вычислять вручную. Или нет?
0
Bytt
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
15.11.2012, 10:25 11
Цитата Сообщение от Fidyum4yk
Т.е. не использовать функцию Pow и вместо нее запустить цикл с перемножением???
Если хотите использовать pow(), перепишите ваше выражение следующим образом:
Код
st=pow(10,tmp) + 0.5;
Или нет?
0
Stiit.mi
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
18.11.2012, 13:58 12
Цитата Сообщение от Bytt
Цитата Сообщение от //Mt
Цитата Сообщение от Fidyum4yk
Единственное чего не могу понять: tmp=3, pow(10,tmp)=999; а если сделать так pow(10,3) в итоге все норм = 1000.
Думаю, что в случае pow(10,3) функция pow() вообще не вызывается, оптимизатор должен подставить константу.... можно посмотреть это в листинге, скажем.
Зря так думаете. Компилятор просто не "знает" что такое функция pow(). Он также ничего не "знает" и о множестве остальных библиотечных функций. Так что в подобных случаях такие функции нужно вычислять вручную. Или нет?

или нет )

Код
int main(void) {

i=0.0;
8003218:   4909         ldr   r1, [pc, #36]   ; (8003240 <main+0x28>)
800321a:   2200         movs   r2, #0
800321c:   2300         movs   r3, #0
800321e:   e9c1 2300    strd   r2, r3, [r1]
i = pow(11.0,11.0);
8003222:   a305         add   r3, pc, #20   ; (adr r3, 8003238 <main+0x20>)
8003224:   e9d3 2300    ldrd   r2, r3, [r3]
8003228:   e9c1 2300    strd   r2, r3, [r1]
i=1.0;
800322c:   4b05         ldr   r3, [pc, #20]   ; (8003244 <main+0x2c>)
800322e:   2200         movs   r2, #0

...

8003236:   4770         bx   lr
8003238:   a654c000    .word   0xa654c000
800323c:   42509b79    .word   0x42509b79
8003240:   20000008    .word   0x20000008
8003244:   3ff00000    .word   0x3ff00000
0
Bytt
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
18.11.2012, 14:39 13
Цитата Сообщение от Stiit.mi
Цитата Сообщение от Bytt
Компилятор просто не "знает" что такое функция pow(). Он также ничего не "знает" и о множестве остальных библиотечных функций. Так что в подобных случаях такие функции нужно вычислять вручную. Или нет?
или нет )

Код
int main(void) {

i=0.0;
8003218:   4909         ldr   r1, [pc, #36]   ; (8003240 <main+0x28>)
800321a:   2200         movs   r2, #0
800321c:   2300         movs   r3, #0
800321e:   e9c1 2300    strd   r2, r3, [r1]
i = pow(11.0,11.0);
8003222:   a305         add   r3, pc, #20   ; (adr r3, 8003238 <main+0x20>)
8003224:   e9d3 2300    ldrd   r2, r3, [r3]
8003228:   e9c1 2300    strd   r2, r3, [r1]
i=1.0;
800322c:   4b05         ldr   r3, [pc, #20]   ; (8003244 <main+0x2c>)
800322e:   2200         movs   r2, #0

...

8003236:   4770         bx   lr
8003238:   a654c000    .word   0xa654c000
800323c:   42509b79    .word   0x42509b79
8003240:   20000008    .word   0x20000008
8003244:   3ff00000    .word   0x3ff00000
Ну и?
0
Stiit.mi
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
18.11.2012, 15:26 14
Цитата Сообщение от Bytt
Цитата Сообщение от Stiit.mi
Цитата Сообщение от Bytt
Компилятор просто не "знает" что такое функция pow(). Он также ничего не "знает" и о множестве остальных библиотечных функций. Так что в подобных случаях такие функции нужно вычислять вручную. Или нет?
или нет )

Код:
int main(void) {

i=0.0;
8003218: 4909 ldr r1, [pc, #36] ; (8003240 <main+0x28>)
800321a: 2200 movs r2, #0
800321c: 2300 movs r3, #0
800321e: e9c1 2300 strd r2, r3, [r1]
i = pow(11.0,11.0);
8003222: a305 add r3, pc, #20 ; (adr r3, 8003238 <main+0x20>)
8003224: e9d3 2300 ldrd r2, r3, [r3]
8003228: e9c1 2300 strd r2, r3, [r1]
i=1.0;
800322c: 4b05 ldr r3, [pc, #20] ; (8003244 <main+0x2c>)
800322e: 2200 movs r2, #0

...

8003236: 4770 bx lr
8003238: a654c000 .word 0xa654c000
800323c: 42509b79 .word 0x42509b79
8003240: 20000008 .word 0x20000008
8003244: 3ff00000 .word 0x3ff00000

Ну и?

Ээээ. По листингу вроде видно, что компилятор оптимизирует и константу подставляет. Или разговор не об этом был?
0
Bytt
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
18.11.2012, 15:33 15
Цитата Сообщение от Stiit.mi
Цитата Сообщение от Bytt
Цитата Сообщение от Stiit.mi
или нет )

Код:
int main(void) {

i=0.0;
8003218: 4909 ldr r1, [pc, #36] ; (8003240 <main+0x28>)
800321a: 2200 movs r2, #0
800321c: 2300 movs r3, #0
800321e: e9c1 2300 strd r2, r3, [r1]
i = pow(11.0,11.0);
8003222: a305 add r3, pc, #20 ; (adr r3, 8003238 <main+0x20>)
8003224: e9d3 2300 ldrd r2, r3, [r3]
8003228: e9c1 2300 strd r2, r3, [r1]
i=1.0;
800322c: 4b05 ldr r3, [pc, #20] ; (8003244 <main+0x2c>)
800322e: 2200 movs r2, #0

...

8003236: 4770 bx lr
8003238: a654c000 .word 0xa654c000
800323c: 42509b79 .word 0x42509b79
8003240: 20000008 .word 0x20000008
8003244: 3ff00000 .word 0x3ff00000
Ну и?

Ээээ. По листингу вроде видно, что константу подставляет. Или разговор не об этом был?
Разговор-то о том. Только здесь после вызова функции переменной сразу присваивается константа. Оптимизирующий компилятор в данном случает может просто проигнгнорировать вызов функции. Нагляднее будет если присвоить значение функции pow какой-нибудь глобальной (лучше внешней) переменной. Или нет?
0
Stiit.mi
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
18.11.2012, 17:10 16
Не, тут все четко. i - глобальная переменная.
Присвоение я сделал для сравнения - тот же набор инструкций, что для присвоения значения, что для предвычисленной функции pow.
0
Bytt
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
18.11.2012, 17:29 17
Цитата Сообщение от Stiit.mi
Не, тут все четко. i - глобальная переменная.
Присвоение я сделал для сравнения - тот же набор инструкций, что для присвоения значения, что для предвычисленной функции pow.
ЕЩЕ РАЗ. Переменной СРАЗУ ПОСЛЕ ВЫЗОВА присваивается новое значение.
Код
i = pow(11.0, 110);
i = 1.0;
Какой будет результат после выполнения этой последовательности? Смысл вызова функции в данном случае какой?
0
Stiit.mi
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
19.11.2012, 12:18 18
Цитата Сообщение от Bytt
Цитата Сообщение от Stiit.mi
Не, тут все четко. i - глобальная переменная.
Присвоение я сделал для сравнения - тот же набор инструкций, что для присвоения значения, что для предвычисленной функции pow.
ЕЩЕ РАЗ. Переменной СРАЗУ ПОСЛЕ ВЫЗОВА присваивается новое значение.
Код
i = pow(11.0, 110);
i = 1.0;
Какой будет результат после выполнения этой последовательности? Смысл вызова функции в данном случае какой?

Ну присваивается. И что? Переменная объявлена как volatile, поэтому она в память каждый раз и записывается. Так бы в регистре повисла. Уж поверь, я проверял и без присваивания.

Неужели проблема посмотреть в десять асмовских команд и увидеть, что один и тот же участок памяти переписывается три раза? В случае наличия анализатора смысла вызова функции запись производилась бы единожды, не?

Конечно, если ты мне что-то другое хочешь доказать, то скажи прямо, а то смысл наводящих вопросов как-то потерялся.
0
19.11.2012, 12:18
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.11.2012, 12:18

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

Оптимизация функции Math.pow
Добрый день уважаемые знатоки. Хотел спросить, можна ли как то оптимизировать функцию math.pow....

Math.Pow для decimal?
Возникла проблема: необходимо извлечь 128-битный корень n-ной степени, но точности double для этого...

Зачем отнимается '0' в строке n += (int)Math.Pow(s[i]-'0',i+1); ?
Вообщем решал простенькую задачку на кодварс,имел реализацию в голове но при проверке выходило...

Как можно преобразовать (int)(Math.Pow(10, i - 1))
{using System; using System.Collections.Generic; using System.Linq; using System.Text; ...

Вычислить значение выражения без использования Math.Pow
Помогите исправить программу. Нужно вычислить : Y=1 - x^2/7! + x^4/7! - ... + (-1)^nx^(2n)/7! без...

Как возвести в квадрат целое число с помощью Math.Pow()?
using System; using System.Collections.Generic; using System.Linq; using System.Text; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.