
https://link3.to/p

Share Dialog
Share Dialog
https://link3.to/p

Subscribe to SIMASAN

Subscribe to SIMASAN
<100 subscribers
<100 subscribers
Оригінал статті:
https://www.aleo.org/post/fixed-point-arithmetic-in-the-zksnark-based-programming-language-leo
Вам цікаво дізнатися, як створити системи на основі блокчейну, які гарантують конфіденційність та масштабованість, здатні вирішувати складні завдання, такі як машинне навчання? Мова програмування LEO спрощує програмування програм на базі ZKP, але за замовчуванням підтримує лише числа, засновані на цілочисельному типі. У цій роботі аналізується конструкція чисел з фіксованою комою в zkSNARKs за допомогою LEO, що дозволяє виконувати обчислення з використанням дробів для широкого спектру застосувань. Дізнайтеся, як представляти дробові числа, і розгляньте компроміси між діапазоном значень, які можна зберегти, і точністю представлених чисел. Ці знання цінні для тих, хто створює складні програми в zkSNARKs.
Системи, засновані на блокчейне, з'являються в багатьох сферах нашого життя в таких галузях, як DeFi або геймінг. Однак багато сучасних блокчейнів потребують більшої конфіденційності та масштабованості, що обмежує діапазон випадків використання. Докази з нульовим рівнем знань і блокчейни, підтримувані zero-knowledge proofs, такі як Aleo, обіцяють забезпечити кращу масштабованість і гарантії конфіденційності, а також включити нові блокчейн-додатки. Це включає нові програми DeFi, більш складні ігри web3 або Програми на основі штучного інтелекту. Багато з цих додатків вимагають представлення різних чисел, включаючи дробові. Aleo поставляється з мовою програмування Leo, що значно полегшує програмування програм, заснованих на нульових знаннях. Однак він підтримує лише числа, засновані на цілочисельному типі. У цій роботі ми аналізуємо структуру чисел з фіксованою комою в zkSNARKs за допомогою Leo, що дозволяє нам також виконувати обчислення з використанням дробів для широкого спектру застосувань.
При реалізації числового запису з фіксованою комою ми можемо використовувати цілочисельний тип, наданий мовою Leo для змінної. Крім того, ми внутрішньо задаємо коефіцієнт масштабування, який визначає цифри, зарезервовані для цілої частини ліворуч від десяткової коми значення, а також визначає дробову частину праворуч від десяткової коми значення. Припустимо, ми хочемо представити значення 1.55 як число з фіксованою комою з точністю до двох цифр після коми. Для цього ми можемо ввести змінну i і призначити їй значення 155, яке є значенням 1,55, помноженим на коефіцієнт масштабування 100:

Тепер ми можемо виконувати математичні обчислення з цією змінною. Наприклад, щоб додати 0.45, ми додаємо 45 (.45 * 100) в програмний код, що призводить до значення змінної 200. Інтерпретуючи вихідні дані програми, нам потрібно розділити значення на коефіцієнт масштабування 100, щоб отримати бажану систему числення з десятковою комою - результат додавання дорівнює 2 у системі числення з десятковою комою.
Аналогічно, ми також можемо виконувати множення. При множенні на 2,50 в десятковій системі числення ми множимо на 250 в системі числення з фіксованою комою, а потім ділимо результат на коефіцієнт масштабування, рівний 100. Наприклад, 2*2,5 =5 у десятковій системі відноситься до 200 * 250/100=500 у системі числення з фіксованою комою. Знову ж таки, інтерпретуючи результат поза системою числення з фіксованою комою, нам потрібно розділити число з фіксованою комою 500 на коефіцієнт масштабування 100, щоб отримати очікуваний результат 5.
Для поділів ми діємо аналогічно множенням, але замість ділення множимо на коефіцієнт масштабування.
Наприклад, 4,5/0,5 = 9 у десятковій системі відноситься до 100*450/50 = 900 у системі числення з фіксованою комою. Розділивши на коефіцієнт масштабування, ми отримуємо очікуваний результат, рівний 9.
Наведені вище приклади показують, що коефіцієнт масштабування визначає кількість цифр дробової частини. Ми використовували масштабний коефіцієнт 10N для N дробових цифр. Як правило, більш високий коефіцієнт масштабування забезпечує більшу точність; однак нам потрібно мати на увазі дійсний діапазон значень для типу.
У наведеному вище прикладі використання u32 загальний діапазон знаходиться між 0 і 2 в 32 ступені -1=4 294 967 295. Через бінарну природу типів загальним поняттям є використання масштабуючих коефіцієнтів s ступенів двійки. При використанні коефіцієнта масштабування 2 в 5 ступені=32 для дробової частини використовується 5 біт, а для цілочисельної частини залишається тільки 27 біт. Таким чином, максимальне число для цілої частини дорівнює 2 в 27 ступені-1=134, 217, 727, а роздільна здатність дробової частини дорівнює 1/25=1/32. Дріб може додати 31/32 до максимального цілого числа, тому максимальне представлене значення знаходиться між 0 і 2 в 27 ступені-1+31/32 =134 217 727,969.
У той же час максимальна помилка подання обчислюється як (1 / S) / 2, тому в цьому прикладі вона дорівнює (1/2 в 5 ступені)/2=1/64=0.015625. Таким чином, більш широкий коефіцієнт масштабування дозволяє нам отримувати більш точні подання дробових чисел, але зменшує розмір цілої частини і, отже, діапазон поданих значень.
Як ми бачимо, існує компроміс між діапазоном значень, які ми можемо зберегти, і точністю чисел, які ми представляємо.
Особливо при множенні або діленні ми можемо зіткнутися з переповненням. Наприклад, припустимо, що ми маємо коефіцієнт масштабування 25 = 32, і ми хочемо помножити 2 в 16 ступені = 65536 на 2 в 6 ступені = 64. Наведений нижче код намагається це зробити.

Для позначення з фіксованою точкою ми повинні помножити обидва числа на коефіцієнт масштабування і помножити 2 в 21 ступені на 2 в 11 ступені, перш ніж ділити з коефіцієнтом масштабування 2 в 5 ступені. Таким чином, просто переглянувши інструкції, ми могли б очікувати виведення коду 2 в 27 ступені.
Однак, коли ми дивимося на вихідні дані, ми отримуємо наступне:

Тимчасовий результат c * D дорівнює 2 в 32 ступені, що просто виходить за межі діапазону типу u32. Таким чином, ми отримали переповнення числа і отримали неправильний результат.
Отже, що ми можемо з цим зробити? Ми могли б використовувати тип u64 замість типу u32 для всіх типів (змінних та вихідних даних), які можуть зберігати числа до 2 в 64 ступені -1. Таким чином, ми отримуємо очікуваний результат 2 в 27 ступенях:

Пам'ятайте, що нам потрібно знову розділити на коефіцієнт масштабування, щоб інтерпретувати результат числа з фіксованою комою в звичайних термінах: 2 в 27 ступені/2 в 5 ступені = 2 в 22 ступені, що є результатом вищезгаданого обчислення 2 в 16 ступені помноженого на 2 в 6 ступені.
Однак при використанні u64 розмір схеми збільшився з 96 до 192 обмежень, фактично подвоївшись у розмірах. Це може призвести до збільшення витрат на перевірку, особливо в складних додатках. Таким чином, альтернативою було б зменшити коефіцієнт масштабування і тим самим потенційно знизити точність представлення чисел.
Використовуючи 2 в 4 ступені як коефіцієнт масштабування замість 2 в 5 ступені лише для типів u32, ми отримуємо такий результат:

Цей результат дорівнює 2 в 26 ступені. Знову ж таки, розділіть його на коефіцієнт масштабування 2 в 4 ступені, і ми отримаємо очікуваний і правильний результат 2 в 22 ступені.
Код, як правило, також працює для негативних чисел. Однак нам потрібно використовувати цілі типи зі знаком. Візьміть до уваги, що знаку потрібен додатковий біт, тому для i32 діапазон цілочисельної частини обчислюється як +- 2 в 31 ступені -1, що перекладається в діапазон від -2147483648 до 2147483647.
Додавання двох чисел, a і b, у форматі з фіксованою комою:

Множення двох чисел, a і b, у форматі з фіксованою комою:

Ділення двох чисел, a і b, у форматі з фіксованою комою:

Ви можете знайти весь код проекту Leo на цій сторінці GitHub
https://github.com/zeroknowledgetutorials/leo-fixed-point-numbers
переклад підготував simasan48#6735
link to the website: https://www.aleo.org/
link to twitter: https://twitter.com/AleoHQ
link to github: https://github.com/AleoHQ
Оригінал статті:
https://www.aleo.org/post/fixed-point-arithmetic-in-the-zksnark-based-programming-language-leo
Вам цікаво дізнатися, як створити системи на основі блокчейну, які гарантують конфіденційність та масштабованість, здатні вирішувати складні завдання, такі як машинне навчання? Мова програмування LEO спрощує програмування програм на базі ZKP, але за замовчуванням підтримує лише числа, засновані на цілочисельному типі. У цій роботі аналізується конструкція чисел з фіксованою комою в zkSNARKs за допомогою LEO, що дозволяє виконувати обчислення з використанням дробів для широкого спектру застосувань. Дізнайтеся, як представляти дробові числа, і розгляньте компроміси між діапазоном значень, які можна зберегти, і точністю представлених чисел. Ці знання цінні для тих, хто створює складні програми в zkSNARKs.
Системи, засновані на блокчейне, з'являються в багатьох сферах нашого життя в таких галузях, як DeFi або геймінг. Однак багато сучасних блокчейнів потребують більшої конфіденційності та масштабованості, що обмежує діапазон випадків використання. Докази з нульовим рівнем знань і блокчейни, підтримувані zero-knowledge proofs, такі як Aleo, обіцяють забезпечити кращу масштабованість і гарантії конфіденційності, а також включити нові блокчейн-додатки. Це включає нові програми DeFi, більш складні ігри web3 або Програми на основі штучного інтелекту. Багато з цих додатків вимагають представлення різних чисел, включаючи дробові. Aleo поставляється з мовою програмування Leo, що значно полегшує програмування програм, заснованих на нульових знаннях. Однак він підтримує лише числа, засновані на цілочисельному типі. У цій роботі ми аналізуємо структуру чисел з фіксованою комою в zkSNARKs за допомогою Leo, що дозволяє нам також виконувати обчислення з використанням дробів для широкого спектру застосувань.
При реалізації числового запису з фіксованою комою ми можемо використовувати цілочисельний тип, наданий мовою Leo для змінної. Крім того, ми внутрішньо задаємо коефіцієнт масштабування, який визначає цифри, зарезервовані для цілої частини ліворуч від десяткової коми значення, а також визначає дробову частину праворуч від десяткової коми значення. Припустимо, ми хочемо представити значення 1.55 як число з фіксованою комою з точністю до двох цифр після коми. Для цього ми можемо ввести змінну i і призначити їй значення 155, яке є значенням 1,55, помноженим на коефіцієнт масштабування 100:

Тепер ми можемо виконувати математичні обчислення з цією змінною. Наприклад, щоб додати 0.45, ми додаємо 45 (.45 * 100) в програмний код, що призводить до значення змінної 200. Інтерпретуючи вихідні дані програми, нам потрібно розділити значення на коефіцієнт масштабування 100, щоб отримати бажану систему числення з десятковою комою - результат додавання дорівнює 2 у системі числення з десятковою комою.
Аналогічно, ми також можемо виконувати множення. При множенні на 2,50 в десятковій системі числення ми множимо на 250 в системі числення з фіксованою комою, а потім ділимо результат на коефіцієнт масштабування, рівний 100. Наприклад, 2*2,5 =5 у десятковій системі відноситься до 200 * 250/100=500 у системі числення з фіксованою комою. Знову ж таки, інтерпретуючи результат поза системою числення з фіксованою комою, нам потрібно розділити число з фіксованою комою 500 на коефіцієнт масштабування 100, щоб отримати очікуваний результат 5.
Для поділів ми діємо аналогічно множенням, але замість ділення множимо на коефіцієнт масштабування.
Наприклад, 4,5/0,5 = 9 у десятковій системі відноситься до 100*450/50 = 900 у системі числення з фіксованою комою. Розділивши на коефіцієнт масштабування, ми отримуємо очікуваний результат, рівний 9.
Наведені вище приклади показують, що коефіцієнт масштабування визначає кількість цифр дробової частини. Ми використовували масштабний коефіцієнт 10N для N дробових цифр. Як правило, більш високий коефіцієнт масштабування забезпечує більшу точність; однак нам потрібно мати на увазі дійсний діапазон значень для типу.
У наведеному вище прикладі використання u32 загальний діапазон знаходиться між 0 і 2 в 32 ступені -1=4 294 967 295. Через бінарну природу типів загальним поняттям є використання масштабуючих коефіцієнтів s ступенів двійки. При використанні коефіцієнта масштабування 2 в 5 ступені=32 для дробової частини використовується 5 біт, а для цілочисельної частини залишається тільки 27 біт. Таким чином, максимальне число для цілої частини дорівнює 2 в 27 ступені-1=134, 217, 727, а роздільна здатність дробової частини дорівнює 1/25=1/32. Дріб може додати 31/32 до максимального цілого числа, тому максимальне представлене значення знаходиться між 0 і 2 в 27 ступені-1+31/32 =134 217 727,969.
У той же час максимальна помилка подання обчислюється як (1 / S) / 2, тому в цьому прикладі вона дорівнює (1/2 в 5 ступені)/2=1/64=0.015625. Таким чином, більш широкий коефіцієнт масштабування дозволяє нам отримувати більш точні подання дробових чисел, але зменшує розмір цілої частини і, отже, діапазон поданих значень.
Як ми бачимо, існує компроміс між діапазоном значень, які ми можемо зберегти, і точністю чисел, які ми представляємо.
Особливо при множенні або діленні ми можемо зіткнутися з переповненням. Наприклад, припустимо, що ми маємо коефіцієнт масштабування 25 = 32, і ми хочемо помножити 2 в 16 ступені = 65536 на 2 в 6 ступені = 64. Наведений нижче код намагається це зробити.

Для позначення з фіксованою точкою ми повинні помножити обидва числа на коефіцієнт масштабування і помножити 2 в 21 ступені на 2 в 11 ступені, перш ніж ділити з коефіцієнтом масштабування 2 в 5 ступені. Таким чином, просто переглянувши інструкції, ми могли б очікувати виведення коду 2 в 27 ступені.
Однак, коли ми дивимося на вихідні дані, ми отримуємо наступне:

Тимчасовий результат c * D дорівнює 2 в 32 ступені, що просто виходить за межі діапазону типу u32. Таким чином, ми отримали переповнення числа і отримали неправильний результат.
Отже, що ми можемо з цим зробити? Ми могли б використовувати тип u64 замість типу u32 для всіх типів (змінних та вихідних даних), які можуть зберігати числа до 2 в 64 ступені -1. Таким чином, ми отримуємо очікуваний результат 2 в 27 ступенях:

Пам'ятайте, що нам потрібно знову розділити на коефіцієнт масштабування, щоб інтерпретувати результат числа з фіксованою комою в звичайних термінах: 2 в 27 ступені/2 в 5 ступені = 2 в 22 ступені, що є результатом вищезгаданого обчислення 2 в 16 ступені помноженого на 2 в 6 ступені.
Однак при використанні u64 розмір схеми збільшився з 96 до 192 обмежень, фактично подвоївшись у розмірах. Це може призвести до збільшення витрат на перевірку, особливо в складних додатках. Таким чином, альтернативою було б зменшити коефіцієнт масштабування і тим самим потенційно знизити точність представлення чисел.
Використовуючи 2 в 4 ступені як коефіцієнт масштабування замість 2 в 5 ступені лише для типів u32, ми отримуємо такий результат:

Цей результат дорівнює 2 в 26 ступені. Знову ж таки, розділіть його на коефіцієнт масштабування 2 в 4 ступені, і ми отримаємо очікуваний і правильний результат 2 в 22 ступені.
Код, як правило, також працює для негативних чисел. Однак нам потрібно використовувати цілі типи зі знаком. Візьміть до уваги, що знаку потрібен додатковий біт, тому для i32 діапазон цілочисельної частини обчислюється як +- 2 в 31 ступені -1, що перекладається в діапазон від -2147483648 до 2147483647.
Додавання двох чисел, a і b, у форматі з фіксованою комою:

Множення двох чисел, a і b, у форматі з фіксованою комою:

Ділення двох чисел, a і b, у форматі з фіксованою комою:

Ви можете знайти весь код проекту Leo на цій сторінці GitHub
https://github.com/zeroknowledgetutorials/leo-fixed-point-numbers
переклад підготував simasan48#6735
link to the website: https://www.aleo.org/
link to twitter: https://twitter.com/AleoHQ
link to github: https://github.com/AleoHQ
No activity yet