Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры 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. Просмотров 5805. Ответов 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
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.11.2012, 12:01
Ответы с готовыми решениями:

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

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

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

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

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

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
13.11.2012, 16:27
omx
0 / 0 / 0
Регистрация: 11.11.2016
13.11.2012, 16:34 5
Цитата Сообщение от Fidyum4yk
Т.е. не использовать функцию Pow и вместо нее запустить цикл с перемножением???
К тому же это будет быстрее по времени.
0
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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.11.2012, 12:18

Как можно преобразовать (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 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru