[C++] Podział zakresu na k równych obszarów ale integerów

Awatar użytkownika
Borneq
Użytkownik
Użytkownik
Posty: 247
Rejestracja: 23 lip 2010, o 07:50
Płeć: Mężczyzna
Lokalizacja: geo:lat=0 geo:lon=0
Podziękował: 13 razy

[C++] Podział zakresu na k równych obszarów ale integerów

Post autor: Borneq »

To coś co ma wiele wspólnego przy powiększaniu rastra metodą Nearest przy niecałkowitej skali powiększenia.

Metoda naiwna:

Kod: Zaznacz cały

void divide_float(int n, int k)
{
    double interval = double(n)/k;
    //double
    for (int i=0; i<k; i++)
    {
        printf("%d %f %f
",i,i*interval, (i+1)*interval);
    }
}
chcę działać na integerach ale i tak mam kłopot z zaokrągleniami:

Kod: Zaznacz cały

void divide_int(int n, int k)
{
    double interval = double(n)/k;
    //int
    uint32_t intPartPos, fracPartPos;
    uint32_t intPartDelta,fracPartDelta,oldFrac;
    intPartPos = 0; fracPartPos = 0;
    intPartDelta = floor(interval);
    fracPartDelta = floor((interval - intPartDelta) * 65536 * 65536);
    for (int i = 0; i<k; i++)
    {
        intPartPos += intPartDelta;
        oldFrac = fracPartPos;
        fracPartPos += fracPartDelta;
        if (oldFrac > fracPartPos) // when LongWord overflow
            intPartPos++;
        printf("%d %d
", i, intPartPos);
    }
}
divide(10,3) zwraca 3,6,9 zamiast 3,6,10 dlatego że w ostatnim jest błąd rzędu \(\displaystyle{ 2^{-32}}\) i to wystarczy by było źle.
Jak wyeliminować liczby zmiennoprzecinkowe i dać dokładnie same inty?
Ostatnio zmieniony 11 lut 2018, o 22:41 przez Afish, łącznie zmieniany 3 razy.
Powód: Temat umieszczony w złym dziale. Poprawa wiadomości.
mihile
Użytkownik
Użytkownik
Posty: 23
Rejestracja: 16 cze 2015, o 06:07
Płeć: Mężczyzna
Lokalizacja: Warszawa
Pomógł: 4 razy

[C++] Podział zakresu na k równych obszarów ale integerów

Post autor: mihile »

Zamienić

Kod: Zaznacz cały

fracPartDelta = floor((interval - intPartDelta) * 65536 * 65536);
na

Kod: Zaznacz cały

fracPartDelta = ceil((interval - intPartDelta) * 65536 * 65536);
i będzie 3, 6, 10
Awatar użytkownika
Borneq
Użytkownik
Użytkownik
Posty: 247
Rejestracja: 23 lip 2010, o 07:50
Płeć: Mężczyzna
Lokalizacja: geo:lat=0 geo:lon=0
Podziękował: 13 razy

[C++] Podział zakresu na k równych obszarów ale integerów

Post autor: Borneq »

Tutaj ceil zadziałało, ale w ogólnym przypadku jest gorzej.
Ale chodzi o rozdzielanie pracy dla wątków - można spokojnie ostatniego elementu nie wyliczać tylko przyjąć ostatni = size().
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

Re: [C++] Podział zakresu na k równych obszarów ale integeró

Post autor: Afish »

Kod: Zaznacz cały

#include <iostream>
#include <cstdio>
using namespace std;

void divide(int n, int k){
	int result = n / k;
	int remainder = n % k;
	int bound = k - remainder;
	int current = 0;
	
	for(int i=0;i<k;++i){
		current += i < bound ? result : result + 1;
		printf("%d ", current);
	}
	
	puts("");
}

int main() {
	divide(10, 3);
	divide(10, 4);
	divide(10, 5);
	divide(11, 3);
	divide(11, 4);
	divide(11, 5);
	divide(11, 6);
	return 0;
}
ODPOWIEDZ