diff --git a/db/db.ddl b/db/db.ddl
index 7e27eb955a61e9ab922a18fdf60801f9699f9e5b..fd3ce6c2c8f86c9b736993a36e2911491ddd23f6 100644
--- a/db/db.ddl
+++ b/db/db.ddl
@@ -107,6 +107,7 @@ CREATE TABLE rounds (
 	score_mode	score_mode	NOT NULL DEFAULT 'basic',	-- mód výsledkovky
 	score_winner_limit	int	DEFAULT NULL,			-- bodový limit na označení za vítěze
 	score_successful_limit	int	DEFAULT NULL,			-- bodový limit na označení za úspěšného řešitele
+	points_step	numeric(2,1)	NOT NULL DEFAULT 1,		-- s jakou přesností jsou přidělovány body (celé aneb 1, 0.5, 0.1)
 	has_messages	boolean		NOT NULL DEFAULT false,		-- má zprávičky
 	UNIQUE (year, category, seq, part)
 );
@@ -162,7 +163,7 @@ CREATE TABLE tasks (
 	round_id	int		NOT NULL REFERENCES rounds(round_id),
 	code		varchar(255)	NOT NULL,			-- např. "P-I-1"
 	name		varchar(255)	NOT NULL,
-	max_points	int		DEFAULT NULL,			-- maximální počet bodů, pokud je nastaven, nelze zadat více bodů
+	max_points	numeric(5,1)	DEFAULT NULL,			-- maximální počet bodů, pokud je nastaven, nelze zadat více bodů
 	UNIQUE (round_id, code)
 );
 
@@ -200,7 +201,7 @@ CREATE TABLE solutions (
 	user_id		int		NOT NULL REFERENCES users(user_id),
 	final_submit	int		DEFAULT NULL REFERENCES papers(paper_id),	-- verze odevzdání, která se má hodnotit
 	final_feedback	int		DEFAULT NULL REFERENCES papers(paper_id),	-- verze komentáře opravovatelů, kterou má vidět účastník
-	points		int		DEFAULT NULL,
+	points		numeric(5,1)	DEFAULT NULL,
 	note		text		NOT NULL DEFAULT '',			-- komentář pro řešitele
 	org_note	text		NOT NULL DEFAULT '',			-- komentář viditelný jen organizátorům
 	PRIMARY KEY (task_id, user_id)
@@ -213,7 +214,7 @@ CREATE TABLE points_history (
 	points_history_id	serial	PRIMARY KEY,
 	task_id		int		NOT NULL REFERENCES tasks(task_id),
 	participant_id	int		NOT NULL REFERENCES users(user_id),
-	points		int		DEFAULT NULL,
+	points		numeric(5,1)	DEFAULT NULL,
 	points_by	int		NOT NULL REFERENCES users(user_id),		-- kdo přidělil body
 	points_at	timestamp with time zone	NOT NULL			-- a kdy
 );
diff --git a/db/upgrade-20210328.sql b/db/upgrade-20210328.sql
new file mode 100644
index 0000000000000000000000000000000000000000..f237e0c816f96b9c2d0ea05d8cdf49acdb715040
--- /dev/null
+++ b/db/upgrade-20210328.sql
@@ -0,0 +1,13 @@
+SET ROLE 'mo_osmo';
+
+ALTER TABLE rounds
+        ADD COLUMN points_step	numeric(2,1)	NOT NULL DEFAULT 1;		-- s jakou přesností jsou přidělovány body (celé aneb 1, 0.5, 0.1)
+
+ALTER TABLE solutions
+        ALTER COLUMN points SET DATA TYPE numeric(5,1);
+
+ALTER TABLE points_history
+        ALTER COLUMN points SET DATA TYPE numeric(5,1);
+
+ALTER TABLE tasks
+        ALTER COLUMN max_points SET DATA TYPE numeric(5,1);
diff --git a/mo/db.py b/mo/db.py
index 5d2c50189a63c27e52d5a01d9a96d216c8eb8e14..81a3c0b89862d05575e4d14607acb8a48199a06d 100644
--- a/mo/db.py
+++ b/mo/db.py
@@ -15,6 +15,7 @@ from sqlalchemy.orm.attributes import get_history
 from sqlalchemy.dialects.postgresql import JSONB
 from sqlalchemy.ext.declarative import declarative_base
 from sqlalchemy.sql.expression import CTE
+from sqlalchemy.sql.sqltypes import Numeric
 from typing import Optional, List, Tuple
 
 import mo
@@ -186,6 +187,15 @@ round_score_mode_names = {
 }
 
 
+# V DB jako numeric(2,1), používá se tak snadněji, než enum
+round_points_step_names = {
+    1: "Celé body",
+    0.5: "Půlbody",
+    0.1: "Desetinné body",
+}
+round_points_step_choices = round_points_step_names.items()
+
+
 class Round(Base):
     __tablename__ = 'rounds'
     __table_args__ = (
@@ -209,6 +219,7 @@ class Round(Base):
     score_mode = Column(Enum(RoundScoreMode, name='score_mode'), nullable=False, server_default=text("'basic'::score_mode"))
     score_winner_limit = Column(Integer)
     score_successful_limit = Column(Integer)
+    points_step = Column(Numeric, nullable=False)
     has_messages = Column(Boolean, nullable=False, server_default=text("false"))
 
     master = relationship('Round', primaryjoin='Round.master_round_id == Round.round_id', remote_side='Round.round_id', post_update=True)
@@ -246,6 +257,11 @@ class Round(Base):
         else:
             return self.state
 
+    def points_step_name(self) -> str:
+        if float(self.points_step) in round_points_step_names:
+            return round_points_step_names[float(self.points_step)]
+        return str(self.points_step)
+
 
 class User(Base):
     __tablename__ = 'users'
@@ -415,7 +431,7 @@ class Task(Base):
     round_id = Column(Integer, ForeignKey('rounds.round_id'), nullable=False)
     code = Column(String(255), nullable=False)
     name = Column(String(255), nullable=False)
-    max_points = Column(Integer)
+    max_points = Column(Numeric)
 
     round = relationship('Round')
 
@@ -524,7 +540,7 @@ class PointsHistory(Base):
     points_history_id = Column(Integer, primary_key=True, server_default=text("nextval('points_history_points_history_id_seq'::regclass)"))
     task_id = Column(Integer, ForeignKey('tasks.task_id'), nullable=False)
     participant_id = Column(Integer, ForeignKey('users.user_id'), nullable=False)
-    points = Column(Integer)
+    points = Column(Numeric)
     points_by = Column(Integer, ForeignKey('users.user_id'), nullable=False)
     points_at = Column(DateTime(True), nullable=False)
 
@@ -540,7 +556,7 @@ class Solution(Base):
     user_id = Column(Integer, ForeignKey('users.user_id'), primary_key=True, nullable=False)
     final_submit = Column(Integer, ForeignKey('papers.paper_id'))
     final_feedback = Column(Integer, ForeignKey('papers.paper_id'))
-    points = Column(Integer)
+    points = Column(Numeric)
     note = Column(Text, nullable=False, server_default=text("''::text"))
     org_note = Column(Text, nullable=False, server_default=text("''::text"))
 
diff --git a/mo/score.py b/mo/score.py
index ccbefbf0909b9c72a216bc2855a1ce85a3cd42fb..01a26d786d8157cb36364e19f69d24ace9abf42c 100644
--- a/mo/score.py
+++ b/mo/score.py
@@ -1,3 +1,4 @@
+import decimal
 from fractions import Fraction
 from sqlalchemy import and_
 from sqlalchemy.orm import joinedload
@@ -56,8 +57,8 @@ class ScoreResult:
     def get_sols_map(self) -> Dict[int, db.Solution]:
         return self._sols[0]
 
-    def get_total_points(self) -> int:
-        sum = 0
+    def get_total_points(self) -> decimal.Decimal:
+        sum = decimal.Decimal(0)
         for sol in self.get_sols():
             if sol.points:
                 sum += sol.points
@@ -67,17 +68,17 @@ class ScoreResult:
 class ScoreTask:
     task: db.Task
     num_solutions: int
-    sum_points: int
+    sum_points: decimal.Decimal
 
     def __init__(self, task: db.Task):
         self.task = task
         self.num_solutions = 0
-        self.sum_points = 0
+        self.sum_points = decimal.Decimal(0)
 
     def get_difficulty(self) -> Fraction:
         if self.num_solutions == 0:
             return Fraction(0)
-        return Fraction(self.sum_points, self.num_solutions)
+        return Fraction(Fraction(self.sum_points), self.num_solutions)
 
     def get_difficulty_str(self) -> str:
         return f'{self.sum_points}/{self.num_solutions}'
diff --git a/mo/web/org_round.py b/mo/web/org_round.py
index 96b94c61c878b66ee0b828bd20545aaa07261e87..70727966cb2d2dcb14936475de2f84c46a3f3587 100644
--- a/mo/web/org_round.py
+++ b/mo/web/org_round.py
@@ -431,6 +431,10 @@ class RoundEditForm(FlaskForm):
         "Hranice bodů pro úspěšné řešitele", validators=[validators.Optional()],
         description="Řešitelé s alespoň tolika body budou označeni za úspěšné řešitele, prázdná hodnota = žádné neoznačovat",
     )
+    points_step = wtforms.SelectField(
+        "Přesnost bodování", choices=db.round_points_step_choices,
+        description="Ovlivňuje možnost zadávání nových bodů, již uložené body nezmění"
+    )
     has_messages = wtforms.BooleanField("Zprávičky pro účastníky (aktivuje možnost vytvářet novinky zobrazované účastníkům)")
     submit = wtforms.SubmitField('Uložit')
 
@@ -450,6 +454,7 @@ def org_round_edit(id: int):
         del form.score_mode
         del form.score_winner_limit
         del form.score_successful_limit
+        del form.points_step
     if form.validate_on_submit():
         form.populate_obj(round)
 
diff --git a/mo/web/templates/org_round.html b/mo/web/templates/org_round.html
index aa1a62a677497f02ed0459b0d5b7c2edb15e8b05..ac93210581020b547d1cd0edba25805f79b6876f 100644
--- a/mo/web/templates/org_round.html
+++ b/mo/web/templates/org_round.html
@@ -61,6 +61,7 @@
 	<tr><td>Výsledková listina<td>{{ round.master.score_mode.friendly_name() }}
 	<tr><td>Hranice bodů pro vítěze<td>{{ round.master.score_winner_limit|none_value(Markup('<i>nenastaveno</i>')) }}
 	<tr><td>Hranice bodů pro úspěšné řešitele<td>{{ round.master.score_successful_limit|none_value(Markup('<i>nenastaveno</i>')) }}
+	<tr><td>Přesnost bodování<td>{{ round.points_step_name() }}
 </table>
 <div style="clear: both;"></div>