www.kn34pc.com

Форум на силистренските радиолюбители
Дата и час: 23 Сеп 2018, 02:09

Часовете са според зоната UTC + 2 часа [ DST ]




Напиши нова тема Отговори на тема  [ 2 мнения ] 
Автор Съобщение
МнениеПубликувано на: 22 Авг 2018, 09:46 
Offline
Аватар

Регистриран на: 07 Дек 2006, 18:24
Мнения: 825
Местоположение: Силистра
За управление на ИС на Silicon Labs Si5351 се нуждаех от метод на съкращение на дроби.

дробна част = b / c,

където b се изчислява, а c е честотата на кварцовия резонатор (25000000, 27000000, +/- няклко kHz около това или всеобщо: за всяка стойност на честотата на кварцовия резонатор)

c е стойнността на делител и е от 1 до (максимално) 1048575.
-----
В библиотеки за управление на Si5351 виждам, че "мащабират" до "знаменател = 1048575. С такъв голям делител, последващите действия са във float.

напр. при b = 2345600, c = 25000000:
b/c = ((b * 1048575) / c) / 1048575 = 98381 / 1048575

Това, че делителят да е почти винаги 1048575 "не ми дава покой" и "чувствам", че нещо може да се промени :yes
-----
В първия случай при целочисленото делене на c резултатът е често "закръглен" и "отрязан надолу":

Проверка:
2345600 / 25000000 = 0,093824
98381 / 1048575 = 0,0938235223994...

Следва наложително е използването на float, а не ми се иска много това.

Все пак се нуждая от действието "съкращаване на дроб":
2345600 / 25000000 = 1466 / 15625 = 0,093824 :crazy


Върнете се в началото
 Профил  
 
МнениеПубликувано на: 22 Авг 2018, 10:37 
Offline
Аватар

Регистриран на: 07 Дек 2006, 18:24
Мнения: 825
Местоположение: Силистра
Някакви опити с прилагане правилата на делене за някои числа (10, 5, 3, 2) направих.
Усложняване и безценно хабене на програмно време обаче видях в добавяне на други делители до достигане на просто число отгоре.

Натъкнах се на:
Reduce the fraction to lowest terms:
https://stackoverflow.com/questions/304 ... west-terms
Код за потвърждение:
  b = frac1;
  a = frac2;

  //Calculate GCD
  c = a % b;

  while (gcd > 0) {
    a = b;
    b = c;
    c = a % b;

    if (c <= 0) {
      gcd = b;
      break;
    }
  }
  //Divide the numerator and denominator with the GCD
  frac1 /= gcd;
  frac2 /= gcd;

Описаният по-горе метод е безценен за мен и ще си го запазя като фаворит. Пренесох го 1:1 в Arduino. Само една инициализация добавих.

Получих "заветните" си
2345600 / 25000000 = 1466 / 15625 :yes :cool
---
След "съкращаване на дроби" последва и "мащабиране", защото при "неподходящ подбрана" честота на кварцовия кристал, до съкращение не се стига.
Поставям си правилото, че честотата "поне" трябва да е четна :rolleyes


Прикачени файлове:
reduce_fraction_03.zip [724 Байта]
7 пъти
Върнете се в началото
 Профил  
 
Покажи мненията от миналия:  Сортирай по  
Напиши нова тема Отговори на тема  [ 2 мнения ] 

Часовете са според зоната UTC + 2 часа [ DST ]


Кой е на линия

Потребители, разглеждащи този форум: 0 регистрирани и 1 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
cron
Форумът се задвижва от phpBB® Forum Software © phpBB Group
Преведено от yarnaudov.com