LINUX.ORG.RU

Golang в крупных проектах возможен (back)?

 


0

6

В enterprise например, да и вообще где нужно много бизнес-логики?

Встречал мнение, что этот язык плохо для этого подходит. Хочу разобраться почему. Там нет фреймворков уровня Laravel/Spring? Скорее всего позже добавят. Отсутствие привычного ООП мешает его юзать? Нельзя обойтись текущими средствами Go?


Ответ на: комментарий от vbr

Погрешности есть в любом процессе. И у телескопа датчики работают с погрешностями. И компьютер вычисляет с погрешностями. Любой адекватный учёный это всё учитывает. Основы этого даже студентам преподают.

Причем тут погрешность? Дело в том что когда люди пользуются каким то инструментом (компьютер и питон в данном случае) они должны обладать какими то минимальными познаниями как с этими инструментом работать. Если бы тот же питон делал непонятные кренделя то миллионы ученых не использовали бы его для научных расчетов.

mx__ ★★★★★
()
Ответ на: комментарий от Aber

Раньше это действительно не имело смысла, сейчас уже достаточно развились.

Даже отключение спекулятивного ветвления против spectre и meltdown не оказала существенного влияния на скорость повседневной работы приложений. А это большие тормоза чем исправление правил округления мантисс около нуля и избавление от сдвига при операциях с разнознаковыми числами.

Obezyan
()
Ответ на: комментарий от ugoday

Но всё же хотелось бы узнать чему равняется сумма 0.1+0.2.

В рамках какой арифметики? Мы ведь уже достаточно большие у мамы, чтобы понимать, что арифметика бывает разной, а не только из первого класса школы?

LamerOk ★★★★★
()
Ответ на: комментарий от mx__

При нормальных правилах работы с плавающий точкой в конце все нули. Потому что при преобразованиях чисел из меньшей точности в большую расширенная часть мантиссы должна состоять из нулей.

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

Это намеренное понижение точности ради хоть какой-то скорости. Буквально выкинули пяток условных переходов из микро кода процов в части операций с числами, но так как эти переходы (if-ы по простому) проверялись при каждой мат операции это дало буст в скорости.

Obezyan
()
Ответ на: комментарий от Obezyan

Узнали бы о так называемом сдвиге (shift), происходящем при округлении положительных и отрицательных частей, о проблеме округления около нуля с обеих сторон к ближайшем честному и нечетному и прочих радостях засунутых в стандарт IEEE754.

Алгоритмы работы со значимой частью (мантиссой) в стандарте имеют косяки, поэтому внезапно при сведении баланса вылезшая лишняя копейка - это «норма».

Чувак, откуда у тебя взялась «копейка» и «сведение баланса» на числах с плавающей точкой? Ты вообще понимаешь, что несоответствие десятичной и двоичной дробей - это базовое математическое свойство самих дробей? Что НЕ СУЩЕСТВУЕТ такого правила округления, которое могло бы исправить математику? Ты вообще догадываешься, что множество иррациональных дробей по основанию 2 и 10 не совпадает 1 в 1 ?

Если у тебя есть хоть этот школьный минимум, как у тебя в финансовых расчётах могли появится двоичные дроби, да к тому же с плавающей точкой ?!?

И js, над которым все ржут как над недоязычком с его NaN

Так никто не ржёт над NaN. Ржут над

 '10' - 3; // => 7
 '10' + 3; // => '103'
LamerOk ★★★★★
()
Ответ на: комментарий от Obezyan
>>> p = 0.1
>>> print('%.32f' % p)
0.10000000000000000555111512312578
>>> 

При нормальных правилах работы с плавающий точкой в конце все нули. Потому что при преобразованиях чисел из меньшей точности в большую расширенная часть мантиссы должна состоять из нулей.

Но в бородатые времена это было очень медленно

Да, ты реально не понимаешь школьной арифметики. Эта разница не вызвана недостаточной точностью или «ошибками» округления, она - следствие конвертации дробей по разному основанию друг в друга.

LamerOk ★★★★★
()
Ответ на: комментарий от LongLiveUbuntu
root@a9893cb1c4a1:~# cat test.pas
program ArrayIndex;
var arr: array[1 .. 10] of Integer;
begin
  arr[11] := 0;
end.

root@a9893cb1c4a1:~# fpc test.pas 
Free Pascal Compiler version 3.2.2+dfsg-32 [2024/01/05] for aarch64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Linux for AArch64
Compiling test.pas
test.pas(4,7) Warning: range check error while evaluating constants (11 must be between 1 and 10)
test.pas(2,5) Note: Local variable "arr" is assigned but never used
Assembling arrayindex
Linking test
5 lines compiled, 0.0 sec
1 warning(s) issued
1 note(s) issued

root@a9893cb1c4a1:~# ./test 
root@a9893cb1c4a1:~# 
vbr ★★★★
()
Ответ на: комментарий от Obezyan

Компьютеры представляют числа в двоичной системе.

Т.е. число 1/10 это сумма дробей 1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + …

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

Отсюда и погрешности.

Если ты захочешь сложить 0.25 и 0.0625, точность будет 100%.

vbr ★★★★
()
Последнее исправление: vbr (всего исправлений: 1)
Ответ на: комментарий от ergo

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

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

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

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

asdpm
()
Ответ на: комментарий от LamerOk

Ты вообще понимаешь, что несоответствие десятичной и двоичной дробей - это базовое математическое свойство самих дробей

Конечно понимаю, об этом речь и не идёт, вы все никак суть нащупать не можете.

Что НЕ СУЩЕСТВУЕТ такого правила округления, которое могло бы исправить математику?

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

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

p = 0.1
print('%.32f' % p)
0.10000000000000000555111512312578

Это не округление, это, внезапно - уточнение. откуда взялись 555111512312578? Мы же просто расширили разрядность мантисы, мы ничего не считали, не округляли, мы просто докинули регистров без значений. В которых зачем-то оставили накопленную ошибку от предыдущих мат операций или вообще, оставшийся мусор.

Почему наш ALU не занулил их ведь мы просто расширяем разрядность? А потому что стандарт говорит - и так сойдёт. Буквально выкинуто одно ветвление с зануленинием ибо медленна! (с)

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

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

Это самый простой пример снижения накопления ошибок округления при расчётах. Есть более сложные и интересные но тут бы азбуку понять.

Obezyan
()
Ответ на: комментарий от Obezyan

Это не округление, это, внезапно - уточнение. откуда взялись 555111512312578?

Это и не округление и не «уточнение», это выбор из числовой оси ближайшего значегия, представимого в формате IEEE 754.

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

Вам уже трижды рассказали что так и задумано, так функционирует ЭВМ. Это азы.

opcode
()
Ответ на: комментарий от mx__

Зависит от степени округления. Те 0.1 и 0.100000000 это дроби разной точности и чтобы их правильно сравнить их нужно привести к одной желаемой точности, вы же записали в левой части сравнения выражение без конкретной точности, это так не работает.

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

Стандарт говорит что нужно просто показать больше разряды с теми ошибками от предыдущих мат операций что там есть. Подразумевается что это будет тоже самое число. А это не так! Потому что 0.1 не равно 0.10 при .2f точности. Понимаете?

Потому что при увеличении точности 0.1 легко станет 0.11 или 0.14 при текущем стандарте. Он тащит ошибки округления меньшей точности в большую при изменении оной.

Obezyan
()
Ответ на: комментарий от Obezyan

мы ничего не считали, не округляли,

Алё, гараж! Мы сделали это ДВАЖДЫ. И то, и другое. Один раз когда конвертировали строку «0.1» в двоичное представление, а второй - когда выводили двоичное представление в виде строки десятичных цифр выражающих десятичную дробь.

Почему наш ALU не занулил их ведь мы просто расширяем разрядность?

Потому что у тебя (и у меня) двоичный ALU, и там вообще нет никаких «десятичных нулей». Тебе выше уже правильно ответили - 1/10 преобразованная в дробь по основанию 2 превращается в бесконечную периодическую дробь. Абсолютно не важно, сколько разрядов ты в эту дробь впихнёшь. Дробь как была так и останется бесконечной и периодической, а значит в какой-то момент, её придётся округлить в какую-то из сторон с ошибкой.

Вы не думаете головой, даже не пытаетесь.

Кто б говорил.

LamerOk ★★★★★
()
Последнее исправление: LamerOk (всего исправлений: 1)
Ответ на: комментарий от opcode

Это и не округление и не «уточнение», это выбор из числовой оси ближайшего значегия, представимого в формате IEEE 754.

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

Вопрос, а какое право вы имеете что-то выбирать если ближайшее к 0.1 с точностью в n знаков будет. 0.10000000..(n-1)? Такое право вам дал стандарт, но ведь вы сами видите что ближайших чисел гораздо больше и выбор мягко говоря - неудачный.

555111512312578 появляется когда вы хотите заглянуть в двоичное представление числа с плавающей запятой

Я не хочу никуда заглядывать, я хочу получить новое число из 0.1. Число с большей точностью. Это не та же дробь с той же точностью. Та дробь получилась при предыдущих расчетах с определённой точностью и я хочу чтобы хвосты округления остались в прошлом. Ушла история. новый такт, новые расчёты с новой точностью, новые дроби.

Obezyan
()
Ответ на: комментарий от vbr
 1 {$RANGECHECKS ON}
 2 program ArrayIndex;
 3 var arr: array[1 .. 10] of Integer;
 4 begin
 5   arr[11] := 0;
 6 end.
fpc /tmp/test.pas 
Free Pascal Compiler version 3.2.2 [2023/08/30] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling /tmp/test.pas
test.pas(5,7) Error: range check error while evaluating constants (11 must be between 1 and 10)
test.pas(7) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode

«Компилятор Паскаля не даст вам выстрелить себе в ногу»

LongLiveUbuntu ★★★★★
()
Последнее исправление: LongLiveUbuntu (всего исправлений: 1)
Ответ на: комментарий от mx__

Извините я разве не простой вопрос задал?

нет конечно, вот это вот что -> 1/10? приведите в десятичный вид с требуемой вам точностью тогда я дам вам ответ.

Obezyan
()
Последнее исправление: Obezyan (всего исправлений: 1)
Ответ на: комментарий от Obezyan

По вашей логике получить число 0.100000000000000000000000000 на компьютере - невозможно :)

Умничка. Ты созрел до осознания факта, что точного значения десятичного 0.1 в двоичной дроби быть не может по определению. А так как IEEE754 использует этот формат - то и там.

LamerOk ★★★★★
()
Ответ на: комментарий от alysnix

как в си. нет исключений

достоверно не знаю - не открывал документацию по голангу и не скачивал комплятор, но насколько сложилось впечатление там две параллельные системы обработки не happy-path ситуаций, что и говорит о кривизне дизайна.

например видел написаную на голанге грубо говоря БД, падавшую с ArrayOutOfBoundsException (или как там в голанге).

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

asdpm
()
Ответ на: комментарий от opcode

Если честно, я подустал биться головой об стену непонимания. Я не учитель, я обезьян.

Вспомните мои слова при новой версии IEEE754 через несколько лет. А пока погода хорошая, я лучше пойду по ветка поскачу в парке.

Obezyan
()
Ответ на: комментарий от LamerOk

Умничка. Ты созрел до осознания факта, что точного значения десятичного 0.1 в двоичной дроби быть не может по определению. А так как IEEE754 использует этот формат - то и там.

Эх, вам оставалось чуть-чуть до понимания что я изначально говорю о двух РАЗНЫХ дробях, а не об одной дроби разной точности.

Ладно, убег гулять. Чао, Буратино.

Obezyan
()
Ответ на: комментарий от Obezyan

По вашей логике получить число 0.100000000000000000000000000 на компьютере - невозможно

Опять попытка сменить тему. Вы сами очень, очень настойчиво задали тему обсуждения: стандарт IEEE 754 и БАГИ, которые вы в нём нашли. Всё ещё в ожидании этих самых «багов».

Число такое на компьютере получить, конечно, можно. Вот оно, прямо на вашем экране. Вы удовлетворены?

тут бы азбуку понять.

opcode
()
Ответ на: комментарий от vbr

Ну и классика:

 1 int main(int argc, char **argv)
 2 {
 3     int arr[10];
 4 
 5     arr[11] = 0;
 6 
 7     return 0;
 8 }

gcc /tmp/test.c 
den@zuiho ~ $ 


gcc -Wall /tmp/test.c 
/tmp/test.c: В функции «main»:
/tmp/test.c:3:9: предупреждение: переменная «arr» определена, но не используется [-Wunused-but-set-variable]
    3 |     int arr[10];

Про индексацию - ни слова.

LongLiveUbuntu ★★★★★
()
Ответ на: комментарий от Obezyan

я лучше пойду по ветка поскачу в парке.

Пока ты будешь там скакать с лианы на лиану хрустя бананом, подумай над следующим: чтобы продемонстрировать наличие проблемы

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

приведи расчёт с числами в IEEE754 где будет видна проблема. Вот у нас два числа - мы сделали операцию и получили один результат в двоичном формате IEEE754. Вот у нас те же два числа - мы сделали ту же операцию и получили другое значение в двоичном формате IEEE754.

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

LamerOk ★★★★★
()
Ответ на: комментарий от Obezyan

я изначально говорю о двух РАЗНЫХ дробях, а не об одной дроби разной точности.

Да хоть о тысяче, но если ты хочешь доказать наличие бага в IEEE 754 - надо показать конкретику, где и как получаются некорректные расчёты. И, разумеется, мы все ожидаем, что ты говоришь о числах в формате IEEE 754, а не распечатке в ASCII хрен пойми откуда взятых десятичных дробей.

LamerOk ★★★★★
()
Ответ на: комментарий от vbr

Да, еще вот такое:

package main

import (
	"fmt"
)

func main() {
	var arr [10]int

	for i := 0; i < 10; i++ {
		arr[i] = i
	}

	fmt.Println("Array is: ", arr)

	arr[11] = 0
}

Пробуем скомпилировать:

 go build 
# test
./main.go:16:6: invalid argument: index 11 out of bounds [0:10]
то же самое поведение, что у Паскаля.

LongLiveUbuntu ★★★★★
()
Ответ на: комментарий от asdpm

а каково представление 1 во float?

Единица, в рамках стандарта IEEE 754, во float представляется точно.

это произведение чего на что?

Она даже не кодируется в битах мантиссы, так как соглашение её задаёт неявно в виде единицы в старшем разряде.

opcode
()
Ответ на: комментарий от opcode

Увидел исправление. Как уже выше ответили, 0.1 в формате IEEE 754 — это ближайшее представление из суммы дробей с 2**n в знаменателях. Можете самостоятельно поэкспериментировать, например, здесь:

Base Convert: IEEE 754 Floating Point

opcode
()
Ответ на: комментарий от Obezyan

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

asdpm
()
Ответ на: комментарий от LongLiveUbuntu

Это лишь примитивный линтер.

{$RANGECHECKS ON}
program ArrayIndex;
var arr: array[1 .. 10] of Integer;
    index: Integer;
begin
  for index := 1 to 11 do
  begin
    arr[index] := 0;
  end;
  Write(arr[index]);
end.

Ну и контрольный в голову:

{$RANGECHECKS ON}
program ArrayIndex;
var arr: array[1 .. 10] of Integer;
    index: Integer;
begin
  for index := 1 to 10 do
  begin
    arr[index] := index;
  end;
  Read(index);
  WriteLn(arr[index]);
end.

Вот именно эта программа не должна компилироваться гипотетическим языком с проверкой индексов во время компиляции.

vbr ★★★★
()
Ответ на: комментарий от Obezyan

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

asdpm
()
Ответ на: комментарий от asdpm

Это ни какое не допущение это сделано специально чтобы 0.1 == 1/10 в Python3х. Все числа с плавающей точкой хранятся в памяти с погрешностью которая задана по умолчанию.

Кстати, кому интересно а он и не знал, в Python2x 0.1 != 1/10, вот реально где была засада …

mx__ ★★★★★
()
Последнее исправление: mx__ (всего исправлений: 1)
Ответ на: комментарий от Obezyan

Кит? Джаваскриптизер что-ли? :)

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

FishHook
()
Ответ на: комментарий от LamerOk

если ты хочешь доказать наличие бага в IEEE 754 - надо показать конкретику

вот простейший пример

(0.1 + 0.2 - 0.3) * 10**17

В любом языке, придерживающимся стандарта, ответ будет

5.5511151231258

Обезьян пытается объяснить что в нормальном стандарте ответом был бы ноль.

Поясню, а то вы туговаты - попробуйте раскрыть скобки:

0.1*10**17 + 0.2*10**17 - 0.3*10**17

Во всех языках соответствующих стандарту будет

0

Вкусно? Это прямое нарушение законов алгебры.

Obezyan
()
Последнее исправление: Obezyan (всего исправлений: 1)
Ответ на: комментарий от FishHook

Вы большой молодец, сам каждый год разбираю новый язык, только вместо гор Хорватии использую ЮБК.

Пока посматриваю на коммерческую разработку на кложе, но брать ещё один проект пока жена не разрешает.

Obezyan
()
Последнее исправление: Obezyan (всего исправлений: 1)